閱讀488 返回首頁    go 技術社區[雲棲]


不能被繼承的類

不能被繼承的類,就是子類在調用父類的構造函數的時候失敗就沒法被集成了,所以可以把析構函數定義為private,因為在調用構造函數的時候,會先檢查析構函數,如果析構是private的,那麼構造函數也沒法被調用。

這個問題和另一篇文章類似https://blog.csdn.net/u011156012/article/details/24979913,我們通過設置共有的static函數來構造和析構。

class A  
{  
private:  
    A(){}  
    ~A(){}  
public:  
    static A* create()  
    {  
        return new A();  
    }  
    void destory()  
    {  
        delete this;  
    }  
};  

這樣的類隻能在堆上實現,也就是隻能通過new出來,而不能在棧上實現。利用虛繼承,我們可以同時在堆上和棧上都可以實現這個類的實例。

template <typename T> class MakeSealed{
         friend T;
private:
        MakeSealed() {}
        ~MakeSealed() {}         
};

class SealedClass: virtual public MakeSealed<SealedClass>{
public:
       SealedClass() {}
       ~SealedClass() {}      
};

在這個SealedClass使用起來和一般的類型沒什麼區別,我們可以在棧上 ,堆上創建實例,盡管類MakeSealed的構造函數是private的,但是因為類SealedClass是它的友元類,因此在SealedClass中可以調用它的私有函數。

但是當我們試圖從SealedClass中繼承一個類並創建它的實例的時候,卻不能編譯通過,例如:

class Try: public SealedClass{
public:
       Try() {}
       ~Try() {}      
};
由於SealedClass是虛繼承自MakeSealed<SealedClass>的,在調用Try時,不會調用SealedClass的構造函數,而是會跳過SealedClass去調用MakeSealed<SealedClass>的構造函數,但是因為Try不是MakeSealed的友元類,所以無法調用其構造函數。這樣就打到了題目的要求,prefect!

最後更新:2017-04-03 12:56:38

  上一篇:go 微信之父張小龍:怎樣做簡單的產品經理?八
  下一篇:go C# 係統應用之注冊表使用詳解