class A{
A(int a = 5){
DoSomething();
A();
}
A(){...}
}
第一个构造函数可以调用第二个吗?
答案 0 :(得分:62)
不是before C++11。
将常用功能提取到单独的功能中。我通常将此函数命名为 construct()。
“所谓的”第二次调用将编译,但在C ++中具有不同的含义:它将构造一个新对象,一个临时对象,然后在语句结束时立即删除。所以,没有。
然而,可以毫无问题地调用析构函数。
答案 1 :(得分:16)
不在C++0x
之前,没有。
但仅仅是出于学术兴趣我想出了一个非常可怕的方法*使用贴片操作员“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;
}
*不,不,我不在生产代码中写这个。
答案 2 :(得分:6)
答案实际上是“是”,但正如其他人所说的那样,它并不能满足您的需求。您当然可以隐式或显式地使用基类的构造函数:
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
};
答案 3 :(得分:3)
不直接。有几种方法可以解决这个问题。
从类的构造函数的初始化列表中,您可以在任何基类和所有成员变量上调用构造函数。
因此,您通常可以重构您的课程并将其拆分为几个较小的类来解决问题。通常执行的代码可以放在成员对象中,也可以放在基类中。然后每个主类的构造函数只需要决定使用哪个构造函数来初始化该成员。
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;
};
答案 4 :(得分:2)
正如Pavel Radzivilovsky在回答中指出的那样,自C++ 11起,这是可能的。它与从子类显式调用父类的构造函数的语法相同。当一个类需要多个构造函数(例如,默认构造函数和具有属性初始化的构造函数)但在所有情况下都必须执行一些操作时,这很有用。这样可以避免代码重复。
这里是一个例子:
class A
{
public:
A()
{
foo();
}
A(Attribute attribute) : A()
{
this->attribute = attribute;
}
//------ some other code --------
private:
Attribute attribute;
void foo()
{...}
//------ some other code -------
};
在这个简单的示例中,我假设在所有情况下都需要调用函数foo()来正确初始化对象。使用这种语法,如果调用第二个构造函数(带有属性初始化),它将首先在默认构造函数中执行操作,然后再执行属性初始化构造函数中的指令。
也可以通过其他方式完成:默认构造函数可以使用默认参数调用另一个构造函数。
在C ++ 11之前,必须复制所有构造函数的通用指令或定义进行实际对象初始化的方法。
答案 5 :(得分:1)
这是一个老问题;然而,
class A{
A(int a = 5){
DoSomething();
A();
}
A(){...}
}
可能是
class A{
A(int a = 5){
*this = A();
DoSomething();
}
A(){...}
}