Снова и снова повторяется, что примитивные типы не имеют конструкторов. Например это _bar
не инициализируется в 0, когда я звоню Foo()
:
class Foo{
int _bar;
};
Так очевидно int()
не конструктор Но что является его имя?
В этом примере я бы сказал, i
является: (построен? инициализирован? одурачен?)
for(int i{}; i < 13; ++i)
Локи Астари упоминает Вот что у техники есть какое-то название.
РЕДАКТИРОВАТЬ в ответ на Майк Сеймур:
#include <iostream>
using namespace std;
class Foo{
int _bar;
public:
void printBar(){ cout << _bar << endl; }
};
int main()
{
Foo foo;
foo.printBar();
Foo().printBar();
return 0;
}
Запуск этого кода в Visual Studio 2013 приводит к:
3382592
3382592
Интересно, что на gcc 4.8.1 получается:
134514651
0
Снова и снова повторяется, что примитивные типы не имеют конструкторов.
Вот так.
Например, этот бар не инициализируется в 0, когда я звоню
Foo()
Да, это. Foo()
определяет инициализацию значения, которая для такого класса без предоставленного пользователем конструктора означает, что он инициализируется нулями перед инициализацией своих членов. Так _bar
заканчивается значением ноль. (Хотя, как отмечено в комментариях, один популярный компилятор неправильно инициализирует такие классы.)
Он не будет инициализирован, если вы вместо этого будете использовать default-initialisation. Вы не можете сделать это с временным; но объявленная переменная Foo f;
или объект new F
будет инициализирован по умолчанию. Инициализация по умолчанию примитивных типов ничего не делает, оставляя их с неопределенным значением.
Это также не было бы инициализировано, если бы класс имел предоставленный пользователем конструктор по умолчанию, и этот конструктор специально не инициализировал _bar
, Опять же, он будет инициализирован по умолчанию, без эффекта.
Очевидно, что int () не является конструктором. Но как это зовут?
В качестве выражения это временное значение, инициализированное значением int
,
Синтаксически это особый случай «явного преобразования типов (функциональная запись)»; но было бы довольно странно использовать этот термин для чего-либо, кроме преобразования типов.
В этом примере я бы сказал,
i
является: (построен? инициализирован? одурачен?)
Инициализирован. Инициализируется списком (с пустым списком), инициализируется значением или инициализируется нулями, если вы хотите быть более конкретным.
Вот что int()
делает (имея в виду, что, грамматически, int
это простой тип спецификатор):
[C++11: 5.2.3/1]:
простой тип спецификатор (7.1.6.2) или имяТипа спецификатор (14.6) с последующим в скобках список_выражений создает значение указанного типа с учетом списка выражений. Если список выражений является одним выражением, выражение преобразования типа эквивалентно (в определенности и если определено в значении) соответствующему приведенному выражению (5.4). Если указанный тип является типом класса, тип класса должен быть завершен. Если в списке выражений указано более одного значения, тип должен быть классом с соответствующим образом объявленным конструктором (8.5, 12.1) и выражениемT(x1, x2, ...)
по сути эквивалентен декларацииT t(x1, x2, ...)
; для какой-то придуманной временной переменнойt
с результатом, являющимся значениемt
в качестве стоимости.
Говоря в разговорной речи, он представляет собой строительство временного int
с пустым инициализатором. Я думаю, что вам будет трудно найти формальное имя для всей конструкции, хотя.
Это не то же самое, что int i{}
, который является полноценным декларация именованного объекта с инициализатором: ваш i
был объявлен, построен и инициализирован.
(Я не думаю, что все это связано с тем, что Локи говорил в своем комментарии к этому связанному ответу.)
Вы можете назвать его псевдо-конструктором, если хотите, отражая терминологию для деструктора (псевдодеструктивные вызовы обсуждаются в C ++ 11 §5.2.4). Тем не мение, int()
значение по умолчанию типа int
то есть 0.
Напомним, что «примитивные типы не имеют конструкторов», это довольно глупое и непрактичное представление. С формальной точки зрения, у примитивных типов нет конструкторов, но те, кто цепляется за это утверждение, не так уж и много в формальном. Кроме того, с точки зрения машинного кода это не так, но, опять же, для тех, кто считает утверждение важным, машинный код подобен магии. Однако есть разница, а именно в том, что с точки зрения машинного кода также обычные не примитивные типы POD могут не иметь конструкторов (формально они имеют конструкторы), и опять же я сомневаюсь, что те, кто выдвигает это утверждение, даже знают о проблемы, то есть я не думаю, что они имеют право иметь мнение. Примерно такие же соображения применимы к любому абсолютному терминологическому утверждению: когда вы слышите такое утверждение, вы можете быть почти уверены, что те, кто его выдвигает, почти не имеют представления о том, что в нем происходит, и что утверждение просто нецелесообразно. & глупо.
Вместо этого, когда вы слышите, например, «построенный» или «вызов конструктора» в контексте примитивных типов, подумайте о том, что это значительно может означать. Формальное это просто вопрос определения. Важным, за исключением обсуждений языкового адвоката, где это в любом случае является данностью, является наличие концептуальной модели, которая работает.
Все сказанное выше, выражение T()
формально это не «конструктор», это не конструктор на уровне машинного кода, и это не конструктор концептуально в любой значимой концептуальной модели.
Это Можно быть конструктор вызов (действительно, определение конструктора по умолчанию состоит в том, что он может вызываться на уровне исходного кода без аргументов), но обратите внимание, что для вызовов конструктора нет категории грамматики.
Имея в виду все вышесказанное, я бы просто назвал это вызовом конструктора, а когда нужно быть более точным, для примитивного типа T
Я бы назвал это вызов псевдо-конструктора.
И если бы кто-то критиковал меня за это, я бы просто бросил им вызов на дуэль.
Обратите внимание, в отношении вашего заявления, что
» Снова и снова повторяется, что примитивные типы не имеют конструкторов. Например, этот бар не инициализируется в 0, когда я звоню
Foo()
выражение Foo()
выполняет инициализацию значения, так что экземпляр (в этом случае) обнуляется.
Что касается общего отсутствия инициализации локальных автоматических переменных примитивных типов без инициализаторов, у вас такая же ситуация с любым типом без определяемого пользователем конструктора, и даже когда есть используемый определенный конструктор, если этот конструктор не инициализирует вещи.
Иногда это становится шоком для начинающих C ++.