提问人:MainID 提问时间:12/13/2009 最后编辑:Michael Krelin - hackerMainID 更新时间:11/10/2018 访问量:44553
构造函数可以在 c++ 中调用另一个构造函数吗?
Can constructor call another constructor in c++?
答:
不是在 C++11 之前。
改为将通用功能提取到单独的函数中。我通常将这个函数命名为 construct()。
“所谓的”第二次调用将编译,但在 C++ 中具有不同的含义:它将构造一个新对象,一个临时对象,然后在语句末尾立即删除。所以,不。
但是,可以毫无问题地调用析构函数。
评论
不是在 C++0x
之前,没有。
但是,只是出于学术兴趣,我想出了一种非常可怕的方法*来使用放置运算符“新”来做到这一点(有人愿意指出这是多么便携?
#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;
}
*地狱不,我没有在生产代码中写这个。
评论
答案实际上是“是”,但正如其他人所建议的那样,它并没有做你想做的事。当然,您可以隐式或显式地使用基类的构造函数:
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
};
不是直接的。有几种方法可以解决这个问题。
从类构造函数的初始值设定项列表中,可以在任何基类和所有成员变量上调用构造函数。
因此,您通常可以重构您的类并将其拆分为几个较小的类来解决问题。通常执行的代码可以放在成员对象或基类中。然后,每个主类的构造函数只需要决定使用哪个构造函数来初始化该成员。
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;
};
这是一个老问题;然而
class A{
A(int a = 5){
DoSomething();
A();
}
A(){...}
}
可能是
class A{
A(int a = 5){
*this = A();
DoSomething();
}
A(){...}
}
评论
*this = A();
正如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 之前,必须复制所有构造函数的通用指令或定义执行实际对象初始化的方法。
评论