我对构造函数链的理解是,当一个类中有多个构造函数(重载的构造函数)时,如果其中一个构造函数试图调用另一个构造函数,那么 此过程称为CONSTRUCTOR CHAINING,在C ++中不受支持。 最近我在阅读在线资料时遇到了这一段......就像这样......
您可能会发现自己处于要编写成员函数以将类重新初始化为默认值的情况。因为您可能已经有一个构造函数来执行此操作,您可能会尝试从您的成员函数中调用构造函数。如前所述,链接构造函数调用在C ++中是非法的。您可以从函数中的构造函数中复制代码,这将起作用,但会导致重复的代码。在这种情况下,最好的解决方案是将代码从构造函数移动到新函数,并让构造函数调用函数来完成初始化数据的工作。
调用构造函数的成员函数是否也属于构造函数链接? 请在C ++中详细介绍这个主题。
答案 0 :(得分:21)
C ++ 11允许构造函数链接(部分)。此功能称为" delegating constructors"。因此,在C ++ 11中,您可以执行以下操作
class Foo
{
public:
Foo(int a) : Foo() { _a = a; }
Foo(char* b) : Foo() { _b = b; }
Foo() { _c = 1.5; }
private:
int _a = 0;
char* _b = nullptr;
double _c;
};
但是,严格的限制是不允许调用另一个构造函数的构造函数初始化任何其他成员。因此,您无法使用委托构造函数执行以下操作:
class Foo
{
public:
Foo(int a) : Foo(), _a(a) { }
Foo(char* b) : Foo(), _b(b) { }
Foo() { _c = 1.5; }
private:
int _a = 0;
char* _b = nullptr;
double _c;
};
MSVC ++ 2013给出了编译错误" C3511:对委托构造函数的调用应该是唯一的成员初始化程序"对于后一个代码示例。
答案 1 :(得分:19)
该段基本上是这样说的:
class X
{
void Init(params) {/*common initing code here*/ }
X(params1) { Init(someParams); /*custom code*/ }
X(params2) { Init(someOtherParams); /*custom code*/ }
};
您也无法从成员函数调用构造函数。你可能觉得你已经做到了,但这是一种错觉:
class X
{
public:
X(int i):i(i){}
void f()
{
X(3); //this just creates a temprorary - doesn't call the ctor on this instance
}
int i;
};
int main()
{
using std::cout;
X x(4);
cout << x.i << "\n"; //prints 4
x.f();
cout << x.i << "\n"; //prints 4 again
}
答案 2 :(得分:3)
这不是文字所说的。它建议你的构造函数调用一个正常且合法的成员函数。这是为了避免再次显式调用ctor并避免在ctor和reset函数之间复制代码。
Foo::Foo() {
Init();
}
void Foo::Reset() {
Init();
}
void Foo::Init() {
// ... do stuff ...
}
答案 3 :(得分:0)
我不确定它(从成员函数调用构造函数)是否有效,但这是一个不好的做法。将初始化代码移动到新函数是逻辑方式。
基本上说,除非你构建......否则不要调用构造函数。
答案 4 :(得分:-1)
当我们从成员函数调用构造函数时,它将临时创建其类型的对象。 如果我们在派生类函数中调用,那么一旦函数超出范围,所有父构造函数也会使用析构函数执行和销毁。
在成员函数中调用构造函数不是一个好习惯,因为它创建了派生的每个类的对象。