2021年2月27日 星期六

[Effective C++] [閱讀心得]: 關於建構函式與解構函式

 為Base class宣告virtual的解構函式


class Base {
public:
    Base();
    ~Base();
    ...
};

class Derived : public Base { ... };

Base *getBase() { ... }

void foo() {
    Base *base = getBase();
    ...
    delete base;
}

這段程式碼中,getBase()回傳一個指標,此指標可能指向一個Base物件或是Derived物件。假設今天base指向了一個Derived的物件,那麼後面的delete base可能會導致物件無法完全銷毀的問題。

會產生此一問題的原因在於,我們想透過一個Base指標來銷毀一個Derived物件,但是Base類別的解構函式並未宣告為virtual。這在C++標準中是一個undefined behavior,而大部分的編譯器的會將其實做為: 在銷毀base指向的物件時只銷毀Base的成份

因此,如果想要完整銷毀base所指向的物件,正確定義Base的方式為:

class Base {
public:
    Base();
    virtual ~Base(); // 將解構函式宣告為virtual
    ...
};

沒有留言:

張貼留言