-4

C++11 中的构造函数允许我们进行构造函数链接。例如,我们可以这样编码:

Class Foo
{
public:
    Foo()
    {
    }   

    Foo(int n): Foo()
    {
    }  
};

我已经尝试在成员初始化列表和代码主体中委托 Foo() 。在这两种情况下,我都会收到相同的返回值。我的问题是这两种方法是否真的有任何区别?如果它们相同,那么应用一个比另一个有什么优势吗?

4

1 回答 1

4

[class.base.init]/6在如何委托构造函数方面相当清楚,不能在构造函数的主体中完成。

一个例子

#include <iostream>

struct A
{
    A() : a(42) {}
    A(int) : A() {}

    int a = 17;
};

struct B
{
    B() : b(42) {}
    B(int) { B(); }

    int b = 17;
};

int main()
{
    A a{0};
    B b{0};
    std::cout << a.a << " " << b.b << std::endl;
}

这个想法很简单:两个structs 中的每一个都暴露了一个构造函数,该构造函数采用一个int(被忽略)。A委托给成员初始化器列表中的默认构造函数(设置a为 42)。B尝试在构造函数的主体中做同样的事情。

此示例编译[godbolt]并调用正确的构造函数 ( A(int)and B(int)),但结果却大不相同:

$ ./a.out
42 17

B的默认构造函数从未被调用

为什么会发生这种情况

所做B(int)的实际上并不是委托构造函数。相反,它构造了一个新的临时类型对象B(就像你可以做的那样B b = B();),并立即丢弃它。它没有以任何方式委派任何事情。

委托构造函数的唯一方法是在成员初始化器列表中调用它。您一次也只能委托给一个构造函数。[这不适用于以非常相似的方式调用的基类的构造函数]

于 2018-05-13T16:07:04.343 回答