在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启到作用。
上面的试验结果表面,在多重继承的时候,如果父类中有同名的成员变量(类似这篇文章中谈及的例子),为了防止二义性,一般要采用虚继承的方式,并且最右边的基类中的那个成员变量会出现在派生类对象中。