Как использование списка инициализаторов членов предотвращает создание избыточного объекта в 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),

Другие вопросы по тегам