簡體   English   中英

用於提升的虛擬析構函數:不可復制的類?

[英]Virtual destructor for boost:noncopyable classes?

我對以下代碼有疑問:

class MyClass : private boost::noncopyable
{
    public:

    MyClass() {}
    virtual ~MyClass() {}
}

class OtherClass : private boost::noncopyable
{
    private:
    MyClass* m_pMyClass;
}

我的想法是MyClass無法使用構造或賦值進行復制。 如果我想支持從MyClass派生類,我需要使用虛擬析構函數,我不想支持。 我不打算創建指向這個類的指針並傳遞它們。

我不想要一個Singleton,我看不出去除虛擬析構函數的缺點。

如果刪除不可復制類的虛擬析構函數,是否會引入潛在問題? 是否有更好的實踐來處理不需要單例的類,但我只想在另一個類中有一個實例而不支持繼承?

不,虛擬析構函數的全部意義在於派生類可以正確地多態破壞。 如果這永遠不會是基類,則不需要它是虛擬的。

一般規則是,如果您的類具有虛函數,則需要虛擬析構函數。 如果它沒有,但仍然是從基類派生的,那么基類(以及你的類)可能需要也可能不需要虛擬析構函數。

boost::noncopyable派生你的類並不真正算作是從基類派生的。 boost::noncopyable更像是一個方便的注釋,備份了幾個聲明,這些聲明將導致編譯器強制執行注釋。 它不是任何傳統意義上的基類。 沒有人會嘗試傳遞指向您的類的指針作為指針或boost::noncopyable引用。 即使他們做了你的虛擬析構函數也無濟於事,因為boost::noncopyable的析構函數不是。

最后,正如評論中指出的那樣,你甚至私下繼承了boost::noncopyable所以就類外的任何人而言,它甚至都不是真正的繼承。

所以真的,不需要把它變成虛擬的析構函數。

我真的不喜歡boost :: noncopyable類作為一個整體。 為什么不直接聲明類的復制構造函數和賦值運算符是私有的而不是定義它們。 這將完成同樣的事情,你可以放棄虛擬析構函數。

Boost只提供一個虛擬析構函數,以便人們可以傳遞boost :: noncopyable對象的多態性,並且仍然可以使它們表現良好。 從技術上講,如果你不打算多態地使用這個類(你甚至可以繼承它),你真的不需要虛擬析構函數。

基類中的虛擬析構函數用於避免部分破壞問題,如:

Base *pBase = new Derived();
delete pBase; 

//if destructor is not made virtual then derived class destructor will never called.

當你私有地繼承一個類時,編譯器不會從派生類到基類執行隱式轉換,如果你確定派生對象永遠不會使用基類指針進行破壞,那么你就不需要在基類中使用虛擬析構函數。

Base *pBase = new Derived(); // will flash error 

boost::noncopyable意味着你不想要制作對象的副本。 您知道這與從對象派生的不同。

如果你不能從對象派生,那么擺脫虛擬析構函數是完全沒錯的。 如果要強制執行“不從此對象派生”策略, 則有一種方法 不幸的是,沒有boost::nonderivable對於你來說這是非常boost::nonderivable


如鏈接中所述,C ++ 11允許您聲明類final

class MyClass : final private boost::noncopyable { ... };

暫無
暫無

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

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