1. 程式人生 > >虛解構函式與純虛擬函式

虛解構函式與純虛擬函式

虛解構函式

通過基類的指標刪除派生類物件時,通常情況只調用基類的解構函式

但是,刪除一個派生類物件時,應該先呼叫派生類的解構函式,然後呼叫基類的解構函式(構造時自頂向下,析構時自底向上)

這種情況會產生記憶體洩漏,最終導致系統應可用記憶體不足而崩潰

解決辦法

把基類的解構函式宣告為virtual,此時派生類的解構函式即使不宣告為virtual也為virtual函式

在呼叫基類的指標刪除派生類物件時,會先呼叫派生類的解構函式,最後呼叫基類的解構函式

一般方法

如果一個類定義了虛擬函式,那麼解構函式也應該定義為虛擬函式

或者一個類打算作為基類使用,也應該講解構函式定義為虛擬函式

純虛擬函式與抽象類

包含純虛擬函式的類叫抽象類,抽象類只能作為基類來派生新類使用,不能建立抽象類的物件

抽象類的指標和引用可以指向由抽象類派生出來的類的物件

class A;             //抽象類

A a;                  //錯誤   
A *pa;              //正確
pa = new A;      //錯誤

在抽象類的成員函式內可以呼叫虛擬函式,但是在建構函式或解構函式內部不能呼叫純虛擬函式。(在成員函式內呼叫虛擬函式是多型,在建構函式和解構函式中呼叫虛擬函式不是多型)

如果一個類從抽象類派生而來,當且僅當它實現了基類中所有的純虛擬函式,它才能成為非抽象類。

class A {
public:
    virtual void f() = 0;
    void g() {
        this->f();    //正確,this指標一定指向一個派生類
    }
    A() {              //此處不能用f()
    }
};

class B : public A {
public:
    void f() {
        cout << "B:f()" << endl;
    }
};

int main() {
    B b;
    b.g();
    return 0;
}