構(gòu)造函數(shù)、析構(gòu)函數(shù)是否要聲明為虛函數(shù)的問題

字號:

構(gòu)造函數(shù)不能聲明為虛函數(shù)的原因是:
    解釋一:所謂虛函數(shù)就是多態(tài)情況下只執(zhí)行一個,而從繼承的概念來講,總是要先構(gòu)造父類對象,然后才能是子類對象,如果構(gòu)造函數(shù)設(shè)為虛函數(shù),那么當(dāng)你在構(gòu)造父類的構(gòu)造函數(shù)時就不得不顯示的調(diào)用構(gòu)造,還有一個原因就是為了防錯,試想如果你在子類中一不小心重寫了個跟父類構(gòu)造函數(shù)一樣的函數(shù),那么你的父類的構(gòu)造函數(shù)將被覆蓋,也即不能完成父類的構(gòu)造.就會出錯.
    解釋二:虛函數(shù)的主要意義在于被派生類繼承從而產(chǎn)生多態(tài). 派生類的構(gòu)造函數(shù)中, 編譯器會加入構(gòu)造基類的代碼, 如果基類的構(gòu)造函數(shù)用到參數(shù), 則派生類在其構(gòu)造函數(shù)的初始化列表中必須為基類給出參數(shù), 就是這個原因.
    析構(gòu)函數(shù)設(shè)為虛函數(shù)的作用:
    解釋:在類的繼承中,如果有基類指針指向派生類,那么用基類指針delete時,如果不定義成虛函數(shù),派生類中派生的那部分無法析構(gòu)。
    例:
    #include "stdafx.h"
    #include "stdio.h"
    class A
    {
    public:
    A();
    virtual ~A();
    };
    A::A()
    {
    }
    A::~A()
    {
    printf("Delete class AP\n");
    }
    class B : public A
    {
    public:
    B();
    ~B();
    };
    B::B()
    {
    }
    B::~B()
    {
    printf("Delete class BP\n");
    }
    int main(int argc, char* argv[])
    {
    A *b=new B;
    delete b;
    return 0;
    }
    輸出結(jié)果為:Delete class B
    Delete class A
    如果把A 的virtual 去掉:
    那就變成了Delete class A
    因此析構(gòu)函數(shù)不聲明為虛函數(shù)容易造成內(nèi)存泄漏。