虛析構(gòu)函數(shù)

虛析構(gòu)函數(shù)

#include <iostream>
#include<string>
#include<cstdlib>

using namespace std;

class A
{
public:
    ~A()
    {
        cout << "A destructor" << endl;
    }
};
class B :public A
{
    ~B()
    {
        cout << "B destructor" << endl;
    }
};

int main()
{
    A *pa = new B;
    delete pa;
    return 0;
}

運(yùn)行結(jié)果:

A destructor    // 只引發(fā)了 A 類的析構(gòu)函數(shù)被調(diào)用,沒有引發(fā) B 類的析構(gòu)函數(shù)

當(dāng)將基類指針指向 new 運(yùn)算符動(dòng)態(tài)生成的派生類對(duì)象時(shí),要通過 delete 來釋放,應(yīng)為該語句是靜態(tài)聯(lián)編的,編譯器不可能知道此時(shí) pa 指向哪個(gè)類型的對(duì)象,它只是根據(jù) pa 類型是 A * ,來決定調(diào)用 A 類的析構(gòu)函數(shù),但實(shí)際上應(yīng)該調(diào)用 B 類的析構(gòu)函數(shù)才符合邏輯。

綜上,delete pa 這樣的語句應(yīng)該根據(jù) pa 所指的對(duì)象,來執(zhí)行相應(yīng)的析構(gòu)函數(shù)。要實(shí)現(xiàn)這點(diǎn),也用到了多態(tài)。因此,需要將基類的析構(gòu)函數(shù)聲明為虛函數(shù),即虛析構(gòu)函數(shù)。

改為:

class A
{
    virtual ~A()
    {
        cout << "A destructor" << endl;
    }
}
運(yùn)行結(jié)果:

B destructor
A destructor

注意

  1. 派生類的析構(gòu)函數(shù)會(huì)自動(dòng)調(diào)用基類的析構(gòu)函數(shù)。

  2. 一般,如果一個(gè)類定義了虛函數(shù),則最好將析構(gòu)函數(shù)也定義成虛函數(shù)。

  3. 只要在基類中某個(gè)函數(shù)被聲明為虛函數(shù),那么在派生類中,同名,同參數(shù)表的成員函數(shù)即使前面不寫 virtual 關(guān)鍵字,也自動(dòng)成為虛函數(shù)。

  4. 編譯器看到是哪個(gè)類的指針,那么就會(huì)認(rèn)為通過它訪問的,就應(yīng)該是哪個(gè)類的成員,編譯器不會(huì)分析基類指針到底指向的是基類對(duì)象還是派生類對(duì)象。

#include <iostream>

using namespace std;

class A
{
public:
    void fun()
    {
        cout << "A called" << endl;
    }
};
class B :public A
{
    void fun()
    {
        cout << "B called" << endl;
    }
};
int main(void)
{
    B b;
    A *pa = &b;
    pa->fun();

    return 0;
}
運(yùn)行結(jié)果:

A called

如果用上多態(tài),則解決了這個(gè)問題:

#include <iostream>

using namespace std;

class A
{
public:
    virtual void fun()
    {
        cout << "A called" << endl;
    }
};
class B :public A
{
    void fun()
    {
        cout << "B called" << endl;
    }
};
int main(void)
{
    B b;
    A *pa = &b;
    pa->fun();

    return 0;
}
運(yùn)行結(jié)果:

B called

由上,只在基類 A 中的 fun 函數(shù)前加了關(guān)鍵字 virtual (line 120),是該函數(shù)及其派生類中的同名,同參數(shù)表中的成員函數(shù)自動(dòng)成為了虛函數(shù),通過基類的指針調(diào)用虛函數(shù)時(shí),就用到了多態(tài)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 2-7虛函數(shù)與虛析構(gòu)函數(shù)實(shí)現(xiàn)原理 [TOC] 1.虛函數(shù)的實(shí)現(xiàn)原理 (1)引入概念:函數(shù)指針。 ? 指向函數(shù)的...
    青_陽閱讀 716評(píng)論 0 1
  • 為什么構(gòu)造函數(shù)不能聲明虛函數(shù) 在C++中,構(gòu)造函數(shù)用于在創(chuàng)建對(duì)象時(shí)進(jìn)行初始化工作,不能聲明為虛函數(shù)。因?yàn)樵趫?zhí)行構(gòu)造...
    tomchan閱讀 309評(píng)論 0 1
  • 通過學(xué)習(xí)我們了解到派生類對(duì)象是由積累部分和派生類不恨構(gòu)成的,那么該派生類對(duì)象是如何被析構(gòu)和夠早的呢? #inclu...
    舌尖上的搬磚漢閱讀 383評(píng)論 0 1
  • 基類的析構(gòu)函數(shù)一般都會(huì)被聲明成虛函數(shù),原因是,若是不設(shè)置成虛函數(shù),在實(shí)現(xiàn)多態(tài)時(shí),將子類對(duì)象賦給基類指針,在析構(gòu)的過...
    Roling閱讀 2,156評(píng)論 1 3
  • 為什么要使用虛析構(gòu)函數(shù) 舉例 打?。?Son 存在的問題實(shí)際上創(chuàng)建的是一個(gè)派生類的對(duì)象,但是調(diào)用的卻是基類的析構(gòu)函...
    Mitchell閱讀 1,114評(píng)論 0 0

友情鏈接更多精彩內(nèi)容