和构造函数类似,析构函数也不能被继承。与构造函数不同的是,在派生类的析构函数中不用显式地调用基类的析构函数,因为每个类只有一个析构函数,编译器知道如何选择,无需程序员干涉。
另外析构函数的执行顺序和构造函数的执行顺序也刚好相反:
-
创建派生类对象时,构造函数的执行顺序和继承顺序相同,即先执行基类构造函数,再执行派生类构造函数。
-
而销毁派生类对象时,析构函数的执行顺序和继承顺序相反,即先执行派生类析构函数,再执行基类析构函数。
具体看实例:
#include <iostream>using namespace std;class A{public:A(){cout<<"A constructor"<<endl;}~A(){cout<<"A destructor"<<endl;}};class B: public A{public:B(){cout<<"B constructor"<<endl;}~B(){cout<<"B destructor"<<endl;}};class C: public B{public:C(){cout<<"C constructor"<<endl;}~C(){cout<<"C destructor"<<endl;}};int main(){C test;return 0;}
运行结果:
A constructor
B constructor
C constructor
C destructor
B destructor
A destructor
下面是一个多继承的实例:
#include <iostream>using namespace std;//基类class BaseA{public:BaseA(int a, int b);~BaseA();protected:int m_a;int m_b;};BaseA::BaseA(int a, int b): m_a(a), m_b(b){cout<<"BaseA constructor"<<endl;}BaseA::~BaseA(){cout<<"BaseA destructor"<<endl;}//基类class BaseB{public:BaseB(int c, int d);~BaseB();protected:int m_c;int m_d;};BaseB::BaseB(int c, int d): m_c(c), m_d(d){cout<<"BaseB constructor"<<endl;}BaseB::~BaseB(){cout<<"BaseB destructor"<<endl;}//派生类class Derived: public BaseA, public BaseB{public:Derived(int a, int b, int c, int d, int e);~Derived();public:void show();private:int m_e;};Derived::Derived(int a, int b, int c, int d, int e): BaseA(a, b), BaseB(c, d), m_e(e){cout<<"Derived constructor"<<endl;}Derived::~Derived(){cout<<"Derived destructor"<<endl;}void Derived::show(){cout<<m_a<<", "<<m_b<<", "<<m_c<<", "<<m_d<<", "<<m_e<<endl;}int main(){Derived obj(1, 2, 3, 4, 5);obj.show();return 0;}
运行结果:
BaseA constructor
BaseB constructor
Derived constructor
1, 2, 3, 4, 5
Derived destructor
BaseB destructorBase
A destructor
从运行结果中还可以发现,多继承形式下析构函数的执行顺序和构造函数的执行顺序相反。