成员初始化器列表的用法如何防止在c ++中创建冗余对象?

时间:2018-12-25 13:06:05

标签: c++ oop object-construction

我有一个问题,关于使用和不使用构造函数成员初始化器列表初始化对象的区别。

在下面的代码片段中,有两个类Test1Test2,每个都有两个构造函数,这两个类的对象是在另一个类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 个答案:

答案 0 :(得分:3)

您的Example构造函数(暗含)等效于

Example() : objTest1(Test1(50)), objTest2()
{
        objTest2 = Test2(50);
}

也就是说,objTest2对象被隐式构造和初始化一次(由编译器插入)。

然后,您体内的对象显式构造并初始化一个临时Test2对象,该对象用于 分配 objTest2


还要注意,在初始化器列表objTest1(Test1(50))中构造一个临时Test1对象,并将其传递给 copy-constructor ,以初始化objTest1(尽管大多数编译器应 elide 进行此复制)。您可以将其简化为简单的objTest1(50)