#c #constructor #initialization
#c #конструктор #инициализация
Вопрос:
Почему s1()
здесь вызывается конструктор?
#include<iostream>
struct s1 {
s1(int tmp) {
}
s1() {
std::printf("s1 invoked");
}
};
struct s2 {
s1 s;
s2(s1amp; s) {
this->s = s;
}
};
int main() {
s1 o1(5);
s2 o2(o1);
return 0;
}
Результат:
s1 invoked
Почему передача по ссылке в s2(s1amp; s)
вызывает s1()
конструктор?
Ответ №1:
Учитывая реализацию s2(s1amp;)
:
s2(s1amp; s) {
this->s = s;
}
Элемент данных s
сначала инициализируется по умолчанию с помощью конструктора по умолчанию, а затем назначается внутри тела конструктора.
Вы должны инициализировать его непосредственно в списке инициализаторов элементов.
s2(s1amp; s) : s(s) // direct-initialize data member s from parameter s
{}
Комментарии:
1. @Ivan Это не будет иметь большого значения при передаче по ссылке, суть в том, как инициализировать элемент данных
s
.
Ответ №2:
Передача s1
из main не создает его по умолчанию. Наличие члена s1
, который не отображается в инициализаторе s2
элемента конструктора, делает.
Кажется, вы хотите
struct s2 {
s1 s;
s2(s1amp; s) : s(s) {
}
};
Ответ №3:
Представьте, что вы вообще не инициализировали s
элемент. Конечно, он не может быть просто не сконструирован. Таким образом, его конструктор по умолчанию вызывается неявно.
Только после того, как все члены (и базовые классы) были инициализированы (сконструированы), тело s2
конструктора (и строка this->s = s
) выполняется. К тому времени s
элемент уже сконструирован по умолчанию. Как предполагают другие ответы, вы можете избежать этого, явно вызвав конструктор в списке инициализаторов членов.