Ответ 1
Это означает, что int id
уже инициализирован, прежде чем вы перейдете к строке id = 0
. Поскольку явный инициализатор не указан, он инициализируется по умолчанию. Кроме того, поскольку это int
, правила инициализации говорят, что они будут иметь некоторое неопределенное значение.
На практике, для int
или любого типа, который чрезвычайно дешев для инициализации, это не имеет большого значения.
Если вместо использования члена int
мы использовали класс, мы могли бы более четко видеть, что происходит на самом деле за кадром:
#include <iostream>
class Verbose {
public:
Verbose() {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
Verbose(int) {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
Verbose(Verbose const &) {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
Verbose & operator=(Verbose const &) {
std::cout << __PRETTY_FUNCTION__ << "\n";
return *this;
}
~Verbose() {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
};
class Object {
public:
Verbose v;
Object() {
v = Verbose(3);
}
};
int main() {
Object o;
}
Этот код выведет:
Verbose::Verbose()
Verbose::Verbose(int)
Verbose &Verbose::operator=(const Verbose &)
Verbose::~Verbose()
Verbose::~Verbose()
Заметим, что мы:
- Мы используем конструктор по умолчанию для создания
v
. - Создаем временный
Verbose(3)
- Затем мы используем оператор присваивания для назначения временной переменной-члену.
- Затем мы уничтожаем временное.
- Когда
Object o
выходит за пределы области видимости, мы уничтожаем переменную-член.
Обратите внимание, что мы в основном построили Verbose v
дважды! Сначала мы использовали конструктор по умолчанию, а затем мы в основном перестроили его с помощью вызова operator=
. Если мы использовали список инициализаторов , мы могли бы уменьшить это до одного вызова Verbose(int)
.