1、什么是虚继承?
虚拟继承(Virtual Inheritance),解决从不同途径继承来的同名的数据成员在内存中有不同的拷贝造成数据不一致问题,将共同基类设置为虚基类。这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数名也只有一个映射。
2、虚继承解决了什么问题?
解决了二义性问题,也节省了内存,避免了数据不一致的问题。
3、虚继承的语法是?
在派生类继承基类时(即在声明派生类的时候),加上一个virtual关键词则为虚拟继承.
class 派生类名:virtual 继承方式 基类名
{
。。。。。。
}
class 派生类: virtual 基类1,virtual 基类2,...,virtual 基类n
{
...//派生类成员声明
};
说明:在多继承情况下,虚基类关键字的作用范围和继承方式关键字相同,只对紧跟其后的基类起作用。声明了虚基类之后,虚基类在进一步派生过程中始终和派生类一起,维护同一个基类子对象的拷贝。
4、执行顺序及优先级
首先执行虚基类的构造函数,多个虚基类的构造函数按照被继承的顺序构造;
执行基类的构造函数,多个基类的构造函数按照被继承的顺序构造;
执行成员对象的构造函数,多个成员对象的构造函数按照申明的顺序构造;
执行派生类自己的构造函数;
析构以与构造相反的顺序执行;
从虚基类直接或间接派生的派生类中的构造函数的成员初始化列表中都要列出对虚基类构造函数的调用。但只有用于建立对象的最派生类的构造函数调用虚基类的构造函数,而该派生类的所有基类中列出的对虚基类的构造函数的调用在执行中被忽略,从而保证对虚基类子对象只初始化一次。
优先级:
在一个成员初始化列表中同时出现对虚基类和非虚基类构造函数的调用时,虚基类的构造函数先于非虚基类的构造函数执行。
代码下载地址:http://download.csdn.net/detail/duan19920101/9464127
执行结果:
当在多条继承路径上有一个公共的基类,在这些路径中的某几条汇合处,这个公共的基类就会产生多个实例(或多个副本),若只想保存这个基类的一个实例,可以将这个公共基类说明为虚基类。
用上述实例来说明这段话就是:类Mid1和类Mid2都继承自公共的基类Base,这个公共的基类会产生多个实例(或多个副本),即在使用类d调用它的print()方法时会产生多义性,导致程序出错,因此我们考虑到使用“虚继承”,将公共基类说明为虚基类,这样在调用时就只保存这个基类的一个实例。
在调用Mid1和Mid2两个类的print()方法时,需要加上类名,即这样做:
d.Mid1::print(); d.Mid2::print();
5、通过输出的比较
1.在多继承情况下,虚基类关键字的作用范围和继承方式关键字相同,只对紧跟其后的基类起作用。
2.声明了虚基类之后,虚基类在进一步派生过程中始终和派生类一起,维护同一个基类子对象的拷贝。
3.观察类构造函数的构造顺序,拷贝也只有一份。
6、与虚函数关系
虚拟继承与虚函数有一定相似的地方,但他们之间是绝对没有任何联系的。
原文参考:http://blog.csdn.net/crystal_avast/article/details/7678704