前言
前面呢, 我們說了C++中實現多態的原理, 其中也說了, 虛函數表和虛函數指針的創建時機,?C++ 詳談多態實現原理-CSDN博客?, 這一節呢, 我們會說說在C++中繼承體系下的另一個知識點, 那就是:?繼承體系下的構造函數和析構函數~~, 主要圍繞兩個問題: 執行順序? 虛析構函數的作用??
繼承體系下的構造函數和析構函數的執行順序
首先我們用一句話來概括, 之后再做詳細解釋: 繼承下, 構造函數按照依賴鏈(孩子依賴父親), 從上往下構造, 析構函數按照依賴鏈, 從下向上析構.
我們從兩個角度來探討, 單繼承 和 多繼承.
單繼承
我們現在在前面代碼的基礎上添加兩個類, Base1和Drive1, Base1作為Base類中的成員變量, Drive1作為Drive中的成員變量, 我們可以設想一些這個情況下的調用順序, 構造Drive之前要先構造Base 和 構造Drive1, 構造Base之前要先構造Base1, 所以其構造順序應該是: Base1, Base, Drive1, Drive, 其析構順序應該是: Drive, Drive1, Base, Base1
#include <iostream>using namespace std;class Base1
{
public:Base1(){cout << "Base1 construction" << endl;}~Base1(){cout << "Base1 destruction" << endl;}
};
class Drive1
{
public:Drive1(){cout << "Drive1 construction" << endl;}~Drive1(){cout << "Drive1 destruction" << endl;}
};
class Base
{
public:Base(){cout << "Base construction" << endl;}~Base(){cout << "Base destruction" << endl;}
private:Base1 b1;
};
class Drive : public Base
{
public:Drive(){cout << "Drive construction" << endl;}~Drive(){cout << "Drive destruction" << endl;}
private:Drive1 d1;
};
int main()
{Drive d;cout << "------------------" << endl;return 0;
}
成員類按照順序構造, 優先于類的構造, 按照相反順序析構.?
多繼承
現在, 代碼有 一個MBase1和MBase2, 一個MDrive多繼承自MBase1和MBase2, 并且MDrive中還有成員變量, MDrive1和MDrive2類型的變量, 構造順序是繼承的順序
#include <iostream>using namespace std;class MBase1
{
public:MBase1(){cout << "MBase1 construction" << endl;}~MBase(){cout << "MBase1 destruction" << endl;}
};
class MBase2
{
public:MBase2(){cout << "MBase2 construction" << endl;}~MBase2(){cout << "MBase2 destruction" << endl;}
};
class MDrive1
{
public:MDrive1(){cout << "MDrive1construction" << endl;}~MDrive1(){cout << "MDrive1destruction" << endl;}
};
class MDrive2
{
public:MDrive2(){cout << "MDrive2 construction" << endl;}~MBase(){cout << "MDrive2 destruction" << endl;}
};
class MDrive : public MBase1, MBase2
{
public:MDrive(){cout << "MDrive construction" << endl;}~MDrive(){cout << "MDrive destruction" << endl;}
private:MDrive1 md1;MDrive2 md2;
};
int main()
{MDrive md;cout << "------------------" << endl;return 0;
}
多繼承中, 除了前面單繼承中的構造順序, 基類是聲明順序構造, 相反順序析構, 上面這一段代碼就是, 先構造MBase1, 再構造MBase2, 再構造MDrive1和MDirve2, 最后構造MDrive.
虛析構函數的作用
作用: 在繼承下, 為了使子類析構函數能夠得到正常調用, 需要將基類的析構函數設置為虛析構函數.
?C++中, 當一個類要被作為基類被繼承是, 應該將這個基類的析構函數手動設置為虛析構函數, 之前說過, C++中如果一個方法是virtual修飾的, 那么在子類繼承之后重寫這個方法, 也是virtual修飾的, C++會將所有的析構函數名稱修改成同一個.
這樣如果父類的析構函數是虛析構函數, 子類中一定是有同名的虛的析構函數, 這樣經過兩次vptr的賦值, 就能正常的調用到虛構造函數了~~