你应看到以下输出:
BaseClass1 constructor.
BaseClass2 constructor.
BaseClass3 constructor.
DerivedClass constructor.
构造函数中的虚函数
我们建议你谨慎调用构造函数中的虚函数。基类构造函数始终在派生类构造函数之前调用,因此基构造函数中调用的函数是基类版本,而非派生类版本。在下面的示例中,构造 DerivedClass 会导致执行 BaseClass 的 print_it() 实现早于 DerivedClass 构造函数导致执行 DerivedClass 的 print_it() 实现:
#include <iostream>
using namespace std;
class BaseClass{
public:
BaseClass(){
print_it();
}
virtual void print_it() {
cout << "BaseClass print_it" << endl;
}
};
class DerivedClass : public BaseClass {
public:
DerivedClass() {
print_it();
}
virtual void print_it(){
cout << "Derived Class print_it" << endl;
}
};
int main() {
DerivedClass dc;
}
这是输出:
BaseClass print_it
Derived Class print_it
构造函数和复合类
包含类类型成员的类称为“复合类”。创建复合类的类类型成员时,调用类自己的构造函数之前,先调用构造函数。当包含的类没有默认构造函数是,必须使用复合类构造函数中的初始化列表。在之前的 StorageBox 示例中,如果将 m_label 成员变量的类型更改为新的 Label 类,则必须调用基类构造函数,并且将 m_label 变量(位于 StorageBox 构造函数中)初始化:
class Label {
public:
Label(const string& name, const string& address) { m_name = name; m_address = address; }
string m_name;
string m_address;
};
class StorageBox : public Box {
public:
StorageBox(int width, int length, int height, Label label)
: Box(width, length, height), m_label(label){}
private:
Label m_label;
};
int main(){
// passing a named Label
Label label1{ "some_name", "some_address" };
StorageBox sb1(1, 2, 3, label1);
// passing a temporary label
StorageBox sb2(3, 4, 5, Label{ "another name", "another address" });
// passing a temporary label as an initializer list
StorageBox sb3(1, 2, 3, {"myname", "myaddress"});
}
委托构造函数
委托构造函数调用同一类中的其他构造函数,完成部分初始化工作。在下面的示例中,派生类具有三个构造函数,第二个构造函数委托第一个,第三个构造函数委托第二个:
#include <iostream>
using namespace std;
class ConstructorDestructor {
public:
ConstructorDestructor() {
cout << "ConstructorDestructor default constructor." << endl;
}
ConstructorDestructor(int int1) {
cout << "ConstructorDestructor constructor with 1 int." << endl;
}
ConstructorDestructor(int int1, int int2) : ConstructorDestructor(int1) {
cout << "ConstructorDestructor constructor with 2 ints." << endl;
throw exception();
}
ConstructorDestructor(int int1, int int2, int int3) : ConstructorDestructor(int1, int2) {
cout << "ConstructorDestructor constructor with 3 ints." << endl;
}
~ConstructorDestructor() {
cout << "ConstructorDestructor destructor." << endl;
}
};
int main() {
ConstructorDestructor dc(1, 2, 3);
}










