作为一个c#开发人员,我习惯了遍历构造函数:

class Test {
    public Test() {
        DoSomething();
    }

    public Test(int count) : this() {
        DoSomethingWithCount(count);
    }

    public Test(int count, string name) : this(count) {
        DoSomethingWithName(name);
    }
}

在c++中有办法做到这一点吗?

我尝试调用类名和使用'this'关键字,但都失败了。


当前回答

如果你想变邪恶,你可以使用“new”操作符:

class Foo() {
    Foo() { /* default constructor deliciousness */ }
    Foo(Bar myParam) {
      new (this) Foo();
      /* bar your param all night long */
    } 
};

似乎对我有用。

edit

正如@ElvedinHamzagic指出的,如果Foo包含一个分配内存的对象,那么该对象可能不会被释放。这使事情更加复杂。

一个更普遍的例子:

class Foo() {
private:
  std::vector<int> Stuff;
public:
    Foo()
      : Stuff(42)
    {
      /* default constructor deliciousness */
    }

    Foo(Bar myParam)
    {
      this->~Foo();
      new (this) Foo();
      /* bar your param all night long */
    } 
};

看起来确实没那么优雅。@JohnIdol的解决方案好多了。

其他回答

测试比决定更容易:) 试试这个:

#include <iostream>

class A {
public:
    A( int a) : m_a(a) {
        std::cout << "A::Ctor" << std::endl;    
    }
    ~A() {
        std::cout << "A::dtor" << std::endl;    
    }
public:
    int m_a;
};

class B : public A {
public:
    B( int a, int b) : m_b(b), A(a) {}
public:
    int m_b;
};

int main() {
    B b(9, 6);
    std::cout << "Test constructor delegation a = " << b.m_a << "; b = " << b.m_b << std::endl;    
    return 0;
}

然后用98 std编译: g++ main.cpp -std=c++98 -o test_1

你会看到:

A::Ctor
Test constructor delegation a = 9; b = 6
A::dtor

所以:)

我建议使用private friend方法,该方法实现了构造函数的应用逻辑,并由各种构造函数调用。这里有一个例子:

假设我们有一个名为StreamArrayReader的类,它带有一些私有字段:

private:
    istream * in;
      // More private fields

我们想定义两个构造函数:

public:
    StreamArrayReader(istream * in_stream);
    StreamArrayReader(char * filepath);
    // More constructors...

其中第二个简单地使用了第一个(当然,我们不想复制前者的实现)。理想情况下,人们会做如下事情:

StreamArrayReader::StreamArrayReader(istream * in_stream){
    // Implementation
}

StreamArrayReader::StreamArrayReader(char * filepath) {
    ifstream instream;
    instream.open(filepath);
    StreamArrayReader(&instream);
    instream.close();
}

然而,这在c++中是不允许的。因此,我们可以定义一个私有友方法,如下所示,它实现了第一个构造函数应该做的事情:

private:
  friend void init_stream_array_reader(StreamArrayReader *o, istream * is);

现在这个方法(因为它是一个朋友)可以访问o的私有字段。然后,第一个构造函数变成:

StreamArrayReader::StreamArrayReader(istream * is) {
    init_stream_array_reader(this, is);
}

注意,这不会为新创建的副本创建多个副本。第二个是:

StreamArrayReader::StreamArrayReader(char * filepath) {
    ifstream instream;
    instream.open(filepath);
    init_stream_array_reader(this, &instream);
    instream.close();
}

也就是说,不是一个构造函数调用另一个构造函数,而是两个构造函数都调用一个私有友元!

不,在c++中,你不能从构造函数调用构造函数。正如沃伦指出的,你能做的是:

使用不同的签名重载构造函数 在参数上使用默认值,使“更简单”的版本可用

请注意,在第一种情况下,不能通过从一个构造函数调用另一个构造函数来减少代码重复。当然,你可以有一个单独的私有/受保护的方法来完成所有的初始化,让构造函数主要处理参数处理。

如果我正确理解你的问题,你是在问你是否可以在c++中调用多个构造函数?

如果这就是你想要的,那不可能。

当然,您可以有多个构造函数,每个构造函数都有唯一的参数签名,然后在实例化一个新对象时调用您想要的那个构造函数。

你甚至可以在构造函数的末尾设置默认参数。

但是你不能有多个构造函数,然后分别调用它们。

c++ 11:是的!

c++ 11及以后的版本也有同样的特性(称为委托构造函数)。

语法与c#略有不同:

class Foo {
public: 
  Foo(char x, int y) {}
  Foo(int y) : Foo('a', y) {}
};

c++ 03:不

不幸的是,在c++ 03中没有办法做到这一点,但是有两种方法来模拟这个:

你可以通过默认参数组合两个(或更多)构造函数: 类Foo { 公众: Foo(char x, int y=0);//结合两个构造函数(char)和(char, int) / /…… }; 使用init方法共享公共代码: 类Foo { 公众: Foo (char x); Foo(char x, int y); / /…… 私人: Void init(char x, int y); }; Foo:: Foo (char x) { Init (x, int(x) + 7); / /…… } Foo::Foo(char x, int y) { init (x, y); / /…… } void Foo::init(char x, int y) { / /…… }

请参阅c++ FAQ条目以获得参考。