成员初始值设定项列表的使用如何防止在c++中创建冗余对象

How usage of member initializer list prevents creation of redundant object in c++?

本文关键字:何防止 c++ 对象 冗余 创建 列表 成员      更新时间:2023-10-16

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

在下面的代码片段中,有两个类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只创建一次)

您的Example构造函数(隐式)等效于

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

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

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


还要注意,在初始化器列表中,objTest1(Test1(50))构造一个临时Test1对象,并将其传递给复制构造函数以初始化objTest1(尽管大多数编译器应该取消此复制)。您可以将其简化为普通的objTest1(50)