virtual inheritance 的妙用--------實現final類 (轉)
virtual inheritance 的妙用--------實現final類
cpp to:cpp_bug@.com">cpp_bug@hotmail.com
一提起virtual inheritance,我們便會立刻把它與multiple inheritance 聯絡起來,因為multiple inheritance會產生一種DDD(dreadful diamond of derivation)的問題。透過virtual inheritance可以解決。關於這點不必多說,下面我們來看virtual inheritance的另外一個應用。
首先我們知道,virtual inheritance所帶來的一個效果就是由派生層次最深的類來完成根類子的建立,即由派生層次最深的類來根類子物件的構造,比方說:
class Base{};
class Derived1:virtual public Base{};
class Derived2:virtual public Base{};
class Mderived:public Derived1,public Derived2{};
對於上面這段程式碼,當用Mderived類構造物件的時候,因為這裡採用了virtual inheritance,並且Mderived類是派生層次最深的類,所以將會由Mderived來完成根類Base子物件的構建,而不是由類Derived1和Derived2來完成。
但是請你注意,並不一定每個派生層次最深的類都具有建立根類子物件的,所以final類的實現恰恰是巧妙的利用了這一點,我們先來看下面這段程式碼:
namespace Private
{
class NoderivedHelper
{
NoderivedHelper(){}
friend class Noderived;
};
}
class Noderived:private virtual Private::NoderivedHelper //此處也可以是public繼承,沒
{ //有影響
…
};
在上面這段程式碼中,Noderived類由於是NoderivedHelper類的友元類,因此它可以完成基類子物件的建立,也就是說它有許可權呼叫NoderivedHelper類的建構函式。但是如果我們想要從Noderived類進行派生,就會發生錯誤。為什麼呢?就是由於這裡採用了virtual inheritance,根類子物件必須由派生層次最深的類來建立的原因。比如:
class D:public Noderived{}
這裡根類子物件必須由D類來建立,但是由於D類不是NoderivedHelper的友元類,因此它沒有許可權呼叫NoderivedHelper類的建構函式,無法對根類子物件進行構建。我想大家對實現final類的基本原理應該已經理解,但是上面的程式碼由於有friend class Noderived;這一行,採用了硬編碼的方式,因此它的適用性很差,我們進行以下改進,去掉friend這一行:
namespace Private
{
class NoderivedHelper
{
protected: //這裡由private變為protected
NoderivedHelper(){}
};
}
class Noderived:private virtual Private::NoderivedHelper //這裡必須是private繼承
{
…
};
ok,現在NoderivedHelper類的適用性明顯增強,而且也可以達到相同的效果,這又是為什麼呢?關鍵是這裡採用了私有繼承,從而NoderivedHelper類將作為Noderived類的私有內部,也就是說NoderivedHelper類的預設建構函式對於從Noderived類派生的類來說變為私有不可訪問。因此當派生層次最深的類建立根類子物件的時候就會出現沒有許可權呼叫根類建構函式的情況,從而發生錯誤。但是現在這個版本還有缺陷,看下面這種情況:
class D: private virtual Private::NoderivedHelper ,public Noderived{}
現在類D就可以從Noderived類中進行派生。因為virtual inheritance使得只有一個根類子物件的副本,並且類D可以從第一個繼承中獲得建立根類子物件的許可權,因此就可以完成物件的構造
下面我們再來改進這個缺陷:
namespace Private
{
class NoderivedHelper
{
protected:
NoderivedHelper(int){}
};
}
class Noderived:private virtual Private::NoderivedHelper
{
public:
Noderived():NoderivedHelper(0){}
};
現在缺陷沒有了,透過那個dummy value,使得即使在class D: private virtual Private::NoderivedHelper ,public Noderived{}的情況下,類D也無法被正常的構造,因為類D在建立根類子物件的時候並不會為NoderivedHelper類的建構函式提供引數,所以無法完成物件的構造。
現在我想大家已經清楚了virtual inheritance所帶來的又一應用了吧:)
(全文完)
reference:
<
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-984974/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 對DBGrid 的巧妙用法實現查詢 (轉)
- 類轉json的基類實現JSON
- Roslyn 編譯器Api妙用:動態生成類並實現介面ROS編譯API
- 理解virtual dom的實現細節-snabbdom
- Connect by實現樹查詢的妙用
- VB實現抽象類 (轉)抽象
- VB.Net中文教程(4) 類別繼承(Inheritance)關係 (轉)繼承
- Java final類Java
- 妙用 background 實現花式文字效果
- java中final類 跟final方法Java
- [轉] V$session 表的妙用Session
- V$session 表的妙用^_^(轉)Session
- Java中常見的final類Java
- Virtual Dom演算法實現筆記演算法筆記
- virtual-dom原理與簡單實現
- 構造解構函式的妙用-成對出現 (轉)函式
- mixin配合class實現多繼承的絕佳妙用繼承
- source命令的一個妙用(轉)
- PHP 物件導向 final類與final方法PHP物件
- 如何實現一個 Virtual DOM 演算法演算法
- 實現類似IE的列印網頁功能 (轉)網頁
- java介面的妙用 (轉)Java
- case class inheritance
- javascript Classical InheritanceJavaScript
- [Relationships]Inheritance
- 如何實現一個 Virtual DOM 及原始碼分析原始碼
- 使用Virtual Private Database實現細粒度訪問控制Database
- InputStream類的實現
- TreeView 的派生類: TreeViewEx 實現 NodeShowToolTip、NodeDoubleClick 事件 (轉)View事件
- 淺談MFC中超類化技術的實現 (轉)
- 【JAVA】筆記(5)--- final;抽象方法;抽象類;介面;解析繼承,關聯,與實現;Java筆記抽象繼承
- Linux中的C語言妙用(轉)LinuxC語言
- Win98“系統資訊”的妙用(轉)
- 網頁中隱藏幀的妙用 (轉)網頁
- 兩步實現類似格瓦拉的轉場動畫動畫
- 說說Prototypal Inheritance
- Important Points for Inheritance in JavaImportJava
- Map類及其主要的實現類