1

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

在下面的代码片段中有两个类Test1Test2每个类都有两个构造函数,这两个类的对象是在另一个类的默认构造函数中创建的Example。的对象Test1是在成员初始化器列表中使用一个参数创建的,而 of 的对象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 只创建一次)
4

1 回答 1

3

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

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

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

然后你在主体内部显式地构造和初始化一个临时Test2对象,用于分配objTest2.


另请注意,在初始化列表中objTest1(Test1(50))构造一个临时Test1对象,并将其传递给复制构造函数以进行初始化objTest1(尽管大多数编译器应该忽略此复制)。您可以将其简化为 plain objTest1(50)

于 2018-12-25T13:12:37.083 回答