Как использование списка инициализаторов членов предотвращает создание избыточного объекта в C++?
У меня есть вопрос, касающийся различий в инициализации объекта с и без списка инициализатора члена конструктора.
В следующем фрагменте кода есть два класса Test1
а также Test2
каждый с двумя конструкторами, объекты этих двух классов создаются в конструкторе по умолчанию другого класса Example
, Объект Test1
создается с одним параметром в списке инициализатора члена, тогда как Test2
создается с одним параметром внутри тела конструктора Example
,
class Test1 {
public:
Test1() { cout << "Test1 is created with no argument"; }
Test1(int a) { cout << "Test1 is created with 1 argument"; }
};
class Test2 {
public:
Test2() { cout << "Test2 is created with no argument"; }
Test2(int a) { cout << "Test2 is created with 1 argument"; }
};
class Example {
public:
Test1 objTest1;
Test2 objTest2;
Example() : objTest1(Test1(50))
{
objTest2 = Test2(50);
}
};
int main()
{
Example e;
}
Вывод вышеуказанного кода:
Test1 is created with 1 argument
Test2 is created with no argument
Test2 is created with 1 argument
Мои вопросы
- Почему объект
Test2
создается дважды? (Тот, который создан без инициализатора члена.) - Что случилось с избыточным объектом
Test2
? Это все еще занимает некоторую память? - Как список инициализаторов членов работает при инициализации переменных членов класса?
- Есть ли какой-то выигрыш в производительности при использовании списка инициализаторов членов? (Так как Test1 создается только один раз)
1 ответ
Ваш Example
Конструктор (неявно) эквивалентен
Example() : objTest1(Test1(50)), objTest2()
{
objTest2 = Test2(50);
}
Это objTest2
Объект создается и инициализируется один раз неявно (это вставляется компилятором).
Затем вы внутри тела явно создаете и инициализируете временный Test2
объект, который используется для назначения objTest2
,
Также обратите внимание, что в списке инициализатора objTest1(Test1(50))
строит временный Test1
объект и передает его конструктору копирования для инициализации objTest1
(хотя большинство компиляторов должны исключить это копирование). Вы можете упростить это как простой objTest1(50)
,