C++多重繼承的時候,虛繼承的使用
阿新 • • 發佈:2019-01-23
說明:
基類Substance
派生類 H 和O 類 繼承Substance
HxOx類多重繼承了H類和O類
1) 在沒有使用虛繼承的時候,程式碼如下(會報錯)
#include <iostream> using namespace std; class Substance{ protected: int atomicity; //原子數 public: Substance(int atomicity = 0){ Substance::atomicity = atomicity; } virtual void ShowInfo() = 0; //純虛擬函式 }; //這裡H直接繼承Substance類,不使用虛擬繼承 class H : public Substance{ protected: bool flammable; //可燃的 public: H(int atomicity = 0,bool flammable = true) : Substance(atomicity){ H::flammable = flammable; } void ShowInfo(){ cout << "氫元素" << endl; } }; //這裡O直接繼承Substance類,不使用虛擬繼承 class O : public Substance{ protected: bool breathable; //可呼吸的 public: O(int atomicity = 0,bool breathable = true) : Substance(atomicity){ O::breathable = breathable; } void ShowInfo(){ cout << "氧元素" << endl; } }; class HxOx : public H , public O{ public: HxOx(int atomicity,bool flammable,bool breathable): Substance(atomicity),H(atomicity,flammable),O(atomicity,breathable){} void ShowInfo(){ cout << "氫氧化合物" << endl; } void ShowDetail(){ cout << "原子數: " << atomicity << endl; cout << "是否可燃: " << flammable << endl; cout << "是否可吸入: " << breathable << endl; } }; int main() { HxOx a(3,false,false); a.ShowInfo(); a.ShowDetail(); return 0; }
出錯原因:
在HxOx類多重繼承H和O類時,由於出現了Substance的兩個副本,編譯器無法找到究竟哪一個atomicity才是應該用的,所以出現瞭如下的錯誤
2) 使用了虛擬繼承的方法,程式碼如下
#include <iostream> using namespace std; class Substance{ protected: int atomicity; //原子數 public: Substance(int atomicity = 0){ Substance::atomicity = atomicity; } virtual void ShowInfo() = 0; //純虛擬函式 }; //這裡H繼承Substance類時使用虛擬繼承 class H : virtual public Substance{ protected: bool flammable; //可燃的 public: H(int atomicity = 0,bool flammable = true) : Substance(atomicity){ H::flammable = flammable; } void ShowInfo(){ cout << "氫元素" << endl; } }; //這裡O繼承Substance類時使用虛擬繼承 class O : virtual public Substance{ protected: bool breathable; //可呼吸的 public: O(int atomicity = 0,bool breathable = true) : Substance(atomicity){ O::breathable = breathable; } void ShowInfo(){ cout << "氧元素" << endl; } }; class HxOx : public H , public O{ public: HxOx(int atomicity,bool flammable,bool breathable): Substance(atomicity),H(atomicity,flammable),O(atomicity,breathable){} void ShowInfo(){ cout << "氫氧化合物" << endl; } void ShowDetail(){ cout << "原子數: " << atomicity << endl; cout << "是否可燃: " << flammable << endl; cout << "是否可吸入: " << breathable << endl; } }; int main() { HxOx a(3,false,false); a.ShowInfo(); a.ShowDetail(); return 0; }
輸出:
氫氧化合物
原子數: 3
是否可燃: 0
是否可吸入: 0
虛擬繼承的機制:
為什麼繼承的時候:virtual public Substance 就不會出錯呢?
其實這是因為,在多重繼承的時候使用了這種虛擬繼承方法之後,編譯器只會建立一個Substance的副本,所以在O和H繼承Substance的時候只建立了一個副本,因此就不會再有成員可能的二義性出現了