2014-06-20

避免使用多重繼承

在OO的觀念中,一個物件可以擁有多種型別。
像是附有橡皮擦的鉛筆,就同時具有橡皮擦與鉛筆的型別。
而我們可能會想要讓這個附有橡皮擦的鉛筆class,
去繼承橡皮擦class與鉛筆class。



舉個例子而言,
假設我們有A,B,C,D四個class,
他們的繼承關係如左圖。

A為superclass,
B和C都去繼承A,
而D去繼承B和C。


程式碼就類似這樣:
class A { public: int var; };
class B : public A { };
class C : public A { };
class D : public B, public C { };

然而,當我們在main()裡創造一個D物件,
並想使用var那個變數時,就會發生問題。
D obj;
obj.var;    // ERROR!! whose var?
obj.B::var;
obj.C::var;

當我們直接寫「obj.var」時,
編譯器會不知道你要用哪個class繼承下來的var,
有可能是B的,也有可能是C的,
因此就會跳出錯誤訊息說,對成員「var」的請求有歧義。
其中一個解決方法,
就是明確指出要用哪個class繼承下來的var,如「obj.B::var」。


另外一種解決方法,
是使用virtual繼承的方式。

如左圖,
B、C都用virtual的方式去繼承A,
則就會確保他們共同繼承到同一個class,
就不會有歧義的問題出現。

class A { public: int var; };
class B : virtual public A { };
class C : virtual public A { };
class D : public B, public C { };

要注意的一點是,
我們通常不會選擇使用多重繼承,
因為很容易造成問題,
每個class的constructor維護也會變得既複雜又麻煩。

Java即把多重繼承的功能移除,
改用interface去達到一個物件同時擁有多種型別的目的。

沒有留言:

張貼留言