构造函数可以在 C++ 中调用另一个构造函数吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1896341/
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-27 21:30:50  来源:igfitidea点击:

Can constructor call another constructor in c++?

c++constructor

提问by MainID

class A{
  A(int a = 5){
    DoSomething();
    A();
  }
  A(){...}
}

Can the first constructor call the second one?

第一个构造函数可以调用第二个构造函数吗?

回答by Pavel Radzivilovsky

Not before C++11.

不是在 C++11 之前

Extract the common functionality into a separate function instead. I usually name this function construct().

而是将通用功能提取到单独的功能中。我通常将这个函数命名为constructor()

The "so-called" second call would compile, but has a different meaning in C++: it would construct a new object, a temporary, which will then be instantly deleted at the end of the statement. So, no.

“所谓的”第二次调用会编译,但在 C++ 中有不同的含义:它会构造一个新对象,一个临时对象,然后在语句结束时立即将其删除。所以不行。

A destructor, however, can be called without a problem.

但是,可以毫无问题地调用析构函数。

回答by Alex B

Not before C++0x, no.

之前C++0x没有,没有。

BUT, just out of academic interestI've come up with a really horrible way* to do it using a placement operator "new" (someone care to point out how portable this is?)

但是,出于学术兴趣,我想出了一种非常可怕的方法* 使用“new”放置操作符(有人关心指出这是多么便携?)

#include <new>
#include <iostream>

class A
{
public:
    A(int i, int j)
        : i_(i), j_(j) { }

    A(int i)
    { new (this) A(i, 13); }

    int i_,j_;
};

int
main() {
    A a1(10,11), a2(10);
    std::cout
        << a1.i_ << ", "
        << a1.j_ << std::endl
        << a2.i_ << ", "
        << a2.j_ << std::endl;
    return 0;
}

*Hell no, I don't write this in the production code.

*不,我不会在生产代码中写这个。

回答by Alex B

The answer is in fact "yes", but as others have suggested, it doesn't do what you want. You can of course use the constructor of a base class, either implicitly or explicitly:

答案实际上是“是”,但正如其他人所建议的那样,它不会做你想要的。您当然可以隐式或显式地使用基类的构造函数:

struct B {
    B() {}
    B( int x ) {}
};

struct A : public B {
    A() {}    // calls B() implicitly
    A( int a, int b ) : B( b ) {} // calls B(int) explicitly
};

回答by jalf

Not directly. There are a few ways to work around this.

不直接。有几种方法可以解决这个问题。

From the initializer list of your class' constructor, you can call a constructor on any base class, and on all member variables.

从类的构造函数的初始值设定项列表中,您可以在任何基类和所有成员变量上调用构造函数。

So you can usually refactor your class and split it into several smaller ones to solve the problem. The commonly executed code can be placed in a member object or perhaps a base class. Then each of the main class' constructors just have to decide which construcotr to use to initialize that member.

因此,您通常可以重构您的类并将其拆分为几个较小的类来解决问题。通常执行的代码可以放在成员对象或基类中。然后每个主类的构造函数只需要决定使用哪个构造函数来初始化该成员。

class B {
  B() {  }
  B(int b) { DoSomething(); }
}
class A{
  A(int a = 5) : b(a) { } // call B's constructor which does something
  A() : b() {} // call B's constructor which does nothing

  B b;
};

回答by PierreW

As pointed out by Pavel Radzivilovsky in his answer, since C++ 11, it is possible. It is the same syntax as for explicitely calling the parent's class constructor from a child class. This is useful when a class needs to have multiple constructors (say, a default constructor and a constructor with attribute initialization) but some operations have to be done in all cases. This allows to avoid code repetitions.

正如 Pavel Radzivilovsky 在他的回答中指出的那样,从C++ 11 开始,这是可能的。它与从子类显式调用父类构造函数的语法相同。当一个类需要有多个构造函数(例如,一个默认构造函数和一个具有属性初始化的构造函数)但某些操作必须在所有情况下完成时,这很有用。这允许避免代码重复。

Here is an example:

下面是一个例子:

class A
{
public:

    A()
    {
         foo();
    }

    A(Attribute attribute) : A()
    {
         this->attribute = attribute;
    }

    //------ some other code --------

private:

    Attribute attribute;
    void foo()
    {...}

    //------ some other code -------
};

In this simple example, I assume that the function foo() needs to be called in all cases for the object to be correctly initialized. With this syntax, if the second constructor (with attribute initialization) is called, it will first perform the operations in the default constructor before executing the instructions in the attribute-initialization constructor.

在这个简单的例子中,我假设在所有情况下都需要调用函数 foo() 才能正确初始化对象。使用此语法,如果调用第二个构造函数(带属性初始化),它将先执行默认构造函数中的操作,然后再执行属性初始化构造函数中的指令。

It can also be done the other way around: the default constructor can call another constructor with default parameters.

也可以反过来:默认构造函数可以使用默认参数调用另一个构造函数。

Before C++ 11, it was necessary to duplicate the common instructions of all constructors or define methods that do the actual object initialization.

在 C++ 11 之前,有必要复制所有构造函数的通用指令或定义执行实际对象初始化的方法。

回答by supaflav

This is an old question; however,

这是一个老问题;然而,

class A{
  A(int a = 5){
    DoSomething();
    A();
  }
  A(){...}
}

could be

可能

class A{
  A(int a = 5){
    *this = A();
    DoSomething();
  }
  A(){...}
}