C++11 中的构造函数允许我们进行构造函数链接。例如,我们可以这样编码:
Class Foo
{
public:
Foo()
{
}
Foo(int n): Foo()
{
}
};
我已经尝试在成员初始化列表和代码主体中委托 Foo() 。在这两种情况下,我都会收到相同的返回值。我的问题是这两种方法是否真的有任何区别?如果它们相同,那么应用一个比另一个有什么优势吗?
C++11 中的构造函数允许我们进行构造函数链接。例如,我们可以这样编码:
Class Foo
{
public:
Foo()
{
}
Foo(int n): Foo()
{
}
};
我已经尝试在成员初始化列表和代码主体中委托 Foo() 。在这两种情况下,我都会收到相同的返回值。我的问题是这两种方法是否真的有任何区别?如果它们相同,那么应用一个比另一个有什么优势吗?
[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;
}
这个想法很简单:两个struct
s 中的每一个都暴露了一个构造函数,该构造函数采用一个int
(被忽略)。A
委托给成员初始化器列表中的默认构造函数(设置a
为 42)。B
尝试在构造函数的主体中做同样的事情。
此示例编译[godbolt]并调用正确的构造函数 ( A(int)
and B(int)
),但结果却大不相同:
$ ./a.out
42 17
B
的默认构造函数从未被调用
所做B(int)
的实际上并不是委托构造函数。相反,它构造了一个新的临时类型对象B
(就像你可以做的那样B b = B();
),并立即丢弃它。它没有以任何方式委派任何事情。
委托构造函数的唯一方法是在成员初始化器列表中调用它。您一次也只能委托给一个构造函数。[这不适用于以非常相似的方式调用的基类的构造函数]