簡體   English   中英

C ++析構函數作為虛函數?

[英]C++ destructors as virtual functions?

我剛才讀到,將C ++析構函數實現為虛函數是一種很好的做法[1]。 為什么會這樣? 這是一般的良好做法嗎? 如果沒有,在什么條件/情況下析構函數是虛函數?

參考

  1. https://www.blackhat.com/presentations/bh-usa-07/Afek/Whitepaper/bh-usa-07-afek-WP.pdf

Herb Sutter在他的文章“虛擬性”中詳細討論了這個主題 准則#4指出“基類析構函數應該是公共的和虛擬的,或者是受保護的和非虛擬的。”

如果您的類未設計或打算用作基類,則沒有理由使用虛擬析構函數聲明它。

如果基類具有析構函數並且它不是虛擬的,那么如果在基類的指針上調用delete,則不會調用任何子類的析構函數。

這可能導致內存泄漏。

class Shape
{
public:
    Shape()
    {
        cout << "Shape constructor called" << endl;
    }
    // This destructor should be virtual!
    ~Shape()
    {
        cout << "~Shape destructor called" << endl;
    }
};

class Triangle : public Shape
{
public:
    Triangle()
    {
        cout << "Triangle constructor called" << endl;
    }
     ~Triangle()
    {
        cout << "Triangle destructor called" << endl;
    }

}

int main(int argc, char* argv[])
{
     Shape* pShape = new Triangle();
     cout << "About to call delete" << endl;
     delete pShape;
}

這將導致:

三角構造函數叫
形狀構造函數調用
即將致電刪除
形狀析構函稱

任何應該在三角形析構函數中釋放的資源現在都已泄露。

來自Scott Meyers的Effective C ++ - “賦予基類虛擬析構函數的規則僅適用於多態基類 - 基類設計允許通過基類接口操作派生類類型。”

如果您的基類中有任何虛函數,那么基類析構函數必須是虛擬的。

未設計為基類或未設計為以多態方式使用的類不應聲明虛擬析構函數

當您的類具有虛擬析構函數時,您將確保將調用派生類中的析構函數。

可以說,如果你的整個類層次結構都是POD或者沒有任何東西可供析構者去做,那么你可能會因為沒有虛擬析構函數而逃脫。 但是,只要你想從類中派生出其他類希望通過指針/引用到多態來使用它們,你就會擁有虛函數,所以添加虛擬析構函數的開銷很小,你永遠不會知道誰將繼承你。 只要任何派生類需要一個非平凡的析構函數並且可以通過指向基類指向它, 就必須有一個虛擬析構函數。

經驗法則:如果您有任何虛函數,請添加虛擬析構函數。

(這里的要點是,如果你沒有虛函數,那么將無法以多態方式使用派生類,因此不太可能通過基類指針刪除需要非平凡破壞的非法子類。它仍然可以完成,它不太可能。)

http://blogs.msdn.com/b/oldnewthing/archive/2004/05/07/127826.aspx

在這個時代,我認為你應該將所有方法都虛擬化,然后再考慮哪些方法不需要。

好的,是的,我用Java完成了大部分的OOP。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM