关于下面的示例代码,为什么基类的析构函数被调用两次?
class Base {
public:
Base() {
std::cout << "Base::Base()" << std::endl;
}
~Base() {
std::cout << "Base::~Base()" << std::endl;
}
};
class Derived : public Base {
public:
Derived() {
std::cout << "Derived::Derived()" << std::endl;
}
~Derived() {
std::cout << "Derived::~Derived()" << std::endl;
}
};
int main() {
Base a = Derived();
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
以下是程序运行时输出的示例:
Base::Base()
Derived::Derived()
Derived::~Derived()
Base::~Base()
Base::~Base()
Run Code Online (Sandbox Code Playgroud)
Joh*_*itb 16
发生的事情称为切片.使用类型Base的对象初始化类型的对象Derived.由于任何类型Derived的对象也Base包含类型的对象(称为"基类子对象"),因此在整个程序中将存在两个Base对象和一个Derived对象.Derived对象(及其类型的基类子对象Base)仅在初始化时Base存在,而剩余对象存在直到结束main.
由于有两个Base对象和一个Derived对象,因此您还将看到另外一个Base destructors运行.
小智 7
正在使用复制构造函数.如果要查看发生了什么,请检查复制构造函数:
Base( const Base & ) {
std::cout << "Base::Base( const Base &)" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
和Derived类似.
请注意,这与析构函数不是虚拟的无关.