在c++中虛繼承的作用主要是在多重繼承的問題上防止二義性的產生。
但是具體什麼是虛繼承呢?就是在被繼承的類前面加virtual關鍵字,這時候被繼承的類就叫做虛基類。
具體請看下面的代碼。
class Person;
class Son1 :virtual public:Person;
class Son2: virtual public:Person;
class Son3:public Son1,public Son2;
如果代碼像上面這樣聲明的話就不會產生二義性。
請看下面代碼:
#include<iostream>
using namespace std;
class Parent
{
public:
int a;
inline Parent()
{
a = 10;
}
};
class Child1:Public Person
{
public:
int a1;
inline Child1()
{
a = 12;
a1 = 10;
}
};
class Child2:public Person
{
public:
int a3;
iline Child2()
{
a = 13;
a3 = 12;
}
};
class Grandchild:public child1,public child2
{
public:
int Grandchild;
inline Grandchild()
{//其實這個繼承的時候就已經產生了二義性,變量a一定在存在這個類當中,但是是12,還是13編譯器是不知道
Grandchild = 14;
}
};
int main(void)
{
Grandchild *Gpc = new Grandchild();
cout<<Gpc->a<<endl;
return 0;
}
通過上面的分析,這段程序一定是編譯不過的,具體的原因是以爲二義性的問題,因爲不知道此時a的值是12還是13因爲Grandchild即繼承了child1裏面a,又繼承了child2裏面的a;這樣會導致編譯器不知道怎麼去選擇,所以程序會報錯。但怎麼去解決這種問題呢?可以通過虛基類或虛繼承的方法去解決二義性的問題
在上面的代碼裏面做下面的改動:
class Child1:Public Person -> class Child1:virtual public Person;
class Child2:Public Person -> class Child2:virtual public Person;
class Grandchild:public child1,public child2不做任何改變
通過上面的代碼可以看出,只是在繼承關係前面加了virtual關鍵字,因爲加了virtual關鍵字以後,Parent object在Grandchild裏面只保留了一份,從而消除了二義性。這裏輸出的結果是13,所以child2類裏面的那個a啓到了作用,但是如果把class Grandchild:public child1,public child2這樣寫?
class Grandchild:public child2,public child1
此時的輸出結果是12,也就是說child1類裏面的a啓到作用。
上面的試驗結果表面,在多重繼承的時候,如果父類中有同名的成員變量(類似這篇文章中談及的例子),爲了防止二義性,一般要採用虛繼承的方式,並且最右邊的基類中的那個成員變量會出現在派生類對象中。