C++中的构造函数链

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7349183/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:48:36  来源:igfitidea点击:

Constructor chaining in C++

c++constructorspecificationsconstructor-chaining

提问by jsp99

My understanding of constructor chaining is that , when there are more than one constructors in a class (overloaded constructors) , if one of them tries to call another constructor,then this process is called CONSTRUCTOR CHAINING , which is not supported in C++ . Recently I came across this paragraph while reading online material.... It goes like this ...

我对构造函数链接的理解是,当一个类中有多个构造函数(重载的构造函数)时,如果其中一个试图调用另一个构造函数,则此过程称为 CONSTRUCTOR CHAINING ,C++ 不支持该过程。最近我在看网上资料的时候看到了这一段……是这样的……

You may find yourself in the situation where you want to write a member function to re-initialize a class back to default values. Because you probably already have a constructor that does this, you may be tempted to try to call the constructor from your member function. As mentioned, chaining constructor calls are illegal in C++. You could copy the code from the constructor in your function, which would work, but lead to duplicate code. The best solution in this case is to move the code from the constructor to your new function, and have the constructor call your function to do the work of initializing the data.

您可能会发现自己处于想要编写成员函数以将类重新初始化为默认值的情况。因为您可能已经有一个执行此操作的构造函数,所以您可能会尝试从您的成员函数调用构造函数。如前所述,链接构造函数调用在 C++ 中是非法的。您可以从函数中的构造函数复制代码,这会起作用,但会导致代码重复。在这种情况下,最好的解决方案是将代码从构造函数移到您的新函数中,并让构造函数调用您的函数来完成初始化数据的工作。

Does a member function calling the constructor also come under constructor chaining ?? Please throw some light on this topic in C++ .

调用构造函数的成员函数是否也属于构造函数链?请在 C++ 中对这个主题有所了解。

采纳答案by Armen Tsirunyan

The paragraph basically says this:

该段落基本上是这样说的:

class X
{
   void Init(params) {/*common initing code here*/ }
   X(params1) { Init(someParams); /*custom code*/ } 
   X(params2) { Init(someOtherParams); /*custom code*/ } 
};

You cannot call a constructor from a member function either. It may seem to you that you've done it, but that's an illusion:

您也不能从成员函数调用构造函数。你可能觉得你已经做到了,但那是一种错觉:

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
}

回答by Serge Rogatch

C++11 allows constructor chaining (partially). This feature is called "delegating constructors". So in C++11 you can do the following

C++11 允许构造函数链接(部分)。此功能称为“委托构造函数”。因此,在 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;
};

However, there is a severe limitation that a constructor that calls another constructor is not allowed to initialize any other members. So you cannot do the following with a delegating constructor:

但是,有一个严重的限制,即调用另一个构造函数的构造函数不能初始化任何其他成员。因此,您不能使用委托构造函数执行以下操作:

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 gives compile error "C3511: a call to a delegating constructor shall be the only member-initializer" for the latter code example.

MSVC++2013 给出了编译错误“C3511:对委托构造函数的调用应是后一个代码示例的唯一成员初始值设定项”。

回答by i_am_jorf

That's not what the text says. It's suggesting your constructor call a member function which is normal and legal. This is to avoid explicitly calling the ctor again and to avoid duplicating code between your ctor and reset function.

课文不是这样说的。它建议您的构造函数调用一个正常且合法的成员函数。这是为了避免再次显式调用 ctor 并避免在 ctor 和 reset 函数之间重复代码。

Foo::Foo() {
  Init();
}

void Foo::Reset() {
  Init();
}

void Foo::Init() {
  // ... do stuff ...
}

回答by Roee Gavirel

I'm not sure if it (calling a constructor from a member function) will work or not, but it's a bad practice. moving the initialize code to a new function is the logic way.

我不确定它(从成员函数调用构造函数)是否有效,但这是一种不好的做法。将初始化代码移动到新函数是逻辑方式。

Basically saying, Don't call the constructor unless you constructing...

基本上是说,除非你构造......,否则不要调用构造函数。

回答by Narayan

when we call constructor from a member function, then it will temporary create a object of its type. in case if we are calling in derived class function then all the parent constructors are also gets executed and destroyed using destructor once function goes out of scope.

当我们从成员函数调用构造函数时,它将临时创建一个其类型的对象。如果我们在派生类函数中调用,那么一旦函数超出范围,所有父构造函数也将使用析构函数执行和销毁。

its not a Good Practice to call the constructors in member functions since it creates objects of every class derived.

在成员函数中调用构造函数不是一个好习惯,因为它创建了每个派生类的对象。