作为一个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引入了委托构造函数:
Delegating constructor
If the name of the class itself appears as class-or-identifier in the
member initializer list, then the list must consist of that one member
initializer only; such constructor is known as the delegating
constructor, and the constructor selected by the only member of the
initializer list is the target constructor
In this case, the target constructor is selected by overload
resolution and executed first, then the control returns to the
delegating constructor and its body is executed.
Delegating constructors cannot be recursive.
class Foo {
public:
Foo(char x, int y) {}
Foo(int y) : Foo('a', y) {} // Foo(int) delegates to Foo(char,int)
};
请注意,委托构造函数是一个全有或全无的提议;如果一个构造函数委托给另一个构造函数,则调用构造函数的初始化列表中不允许有任何其他成员。如果只初始化一次const/reference成员,这是有意义的。
如果你想变邪恶,你可以使用“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
所以:)
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条目以获得参考。
c++ 11:是的!
c++ 11及以后的版本也有同样的特性(称为委托构造函数)。
语法与c#略有不同:
class Foo {
public:
Foo(char x, int y) {}
Foo(int y) : Foo('a', y) {}
};
c++ 03:不
值得指出的是,你可以在你的构造函数中调用父类的构造函数,例如:
class A { /* ... */ };
class B : public A
{
B() : A()
{
// ...
}
};
但是,在c++ 03之前,你不能调用同一个类的另一个构造函数。