作为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'关键字,但都失败了.
C++ 11:是的!
C++ 11及更高版本具有相同的功能(称为委托构造函数).
语法与C#略有不同:
class Foo { public: Foo(char x, int y) {} Foo(int y) : Foo('a', y) {} };
C++ 03:没有
不幸的是,在C++ 03中没有办法做到这一点,但有两种模拟方法:
您可以通过默认参数组合两个(或更多)构造函数:
class Foo { public: Foo(char x, int y=0); // combines two constructors (char) and (char, int) // ... };
使用init方法共享公共代码:
class Foo { public: Foo(char x); Foo(char x, int y); // ... private: 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条目以供参考.
不,你不能在C++ 03中调用另一个构造函数(称为委托构造函数).
这在C++ 11(又名C++ 0x)中有所改变,它增加了对以下语法的支持:(
来自维基百科的示例)
class SomeType { int number; public: SomeType(int newNumber) : number(newNumber) {} SomeType() : SomeType(42) {} };
我相信你可以从构造函数中调用构造函数.它将编译并运行.我最近看到有人这样做,它在Windows和Linux上运行.
它只是没有做你想要的.内部构造函数将构造一个临时本地对象,一旦外部构造函数返回,该对象就会被删除.它们也必须是不同的构造函数,否则您将创建递归调用.
参考:https://isocpp.org/wiki/faq/ctors#init-methods
值得指出的是,您可以在构造函数中调用父类的构造函数,例如:
class A { /* ... */ }; class B : public A { B() : A() { // ... } };
但是,不,你不能调用同一个类的另一个构造函数.
在C++ 11中,构造函数可以调用另一个构造函数重载:
class Foo { int d; public: Foo (int i) : d(i) {} Foo () : Foo(42) {} //New to C++11 };
此外,成员也可以像这样初始化.
class Foo { int d = 5; public: Foo (int i) : d(i) {} };
这应该消除了创建初始化辅助方法的需要.并且仍然建议不要在构造函数或析构函数中调用任何虚函数,以避免使用任何可能未初始化的成员.
如果你想成为邪恶的,你可以使用就地"新"运算符:
class Foo() { Foo() { /* default constructor deliciousness */ } Foo(Bar myParam) { new (this) Foo(); /* bar your param all night long */ } };
似乎为我工作.
编辑
正如@ElvedinHamzagic指出的那样,如果Foo包含一个分配内存的对象,那么该对象可能不会被释放.这使事情进一步复杂化.
一个更一般的例子:
class Foo() { private: std::vectorStuff; public: Foo() : Stuff(42) { /* default constructor deliciousness */ } Foo(Bar myParam) { this->~Foo(); new (this) Foo(); /* bar your param all night long */ } };
看起来有点不那么优雅,当然.@ JohnIdol的解决方案要好得多.
不,在C++中,您无法从构造函数中调用构造函数.沃伦指出,你能做的是:
使用不同的签名重载构造函数
在参数上使用默认值,以使"更简单"的版本可用
请注意,在第一种情况下,您无法通过从另一个构造函数调用来减少代码重复.您当然可以使用一个单独的private/protected方法来执行所有初始化,并让构造函数主要处理参数处理.
简而言之,您不能在C ++ 11之前。
C ++ 11引入了委托构造函数:
委托构造函数
如果类本身的名称在成员初始值设定项列表中显示为class-or-identifier,则该列表必须仅由该一个成员初始值设定项组成;这样的构造函数称为委托构造函数,并且由初始化程序列表的唯一成员选择的构造函数是目标构造函数
在这种情况下,将通过重载分辨率选择目标构造函数并首先执行它,然后控件返回到委托构造函数并执行其主体。
委托构造函数不能是递归的。
class Foo { public: Foo(char x, int y) {} Foo(int y) : Foo('a', y) {} // Foo(int) delegates to Foo(char,int) };
请注意,委派构造函数是一个全有或全无的提议。如果一个构造函数委托给另一个构造函数,则不允许调用构造函数在其初始化列表中包含任何其他成员。如果您考虑一次初始化const / reference成员,并且只初始化一次,则这很有意义。