1. 程式人生 > >C++多重繼承的時候,虛繼承的使用

C++多重繼承的時候,虛繼承的使用

說明:

基類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的時候只建立了一個副本,因此就不會再有成員可能的二義性出現了