1.概括
创新互联长期为近千家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为保康企业提供专业的成都网站建设、做网站,保康网站改版等技术服务。拥有10余年丰富建站经验和众多成功案例,为您定制开发。
在CPlusPlus多继承编程中时常遇到这样一个问题--若子类实现多个基类或接口继承,多基类或接口中存在成员名相同,在客户与实现类之间的通信时编译器报错“不能这样使用,会产生二义性”由于这个问题的解决方法很多。比如说,可以把相同的成员名给改过来。但是,从专业的角度,可能虚拟继承会解决这个问题。那接下来我看看c++是怎么避免这种问题的。
2.概念
当在多条继承路径上有一个公共的基类,在这些路径中的某几条汇合处,这个公共的基类就会产生多个实例(或多个副本),若只想保存这个基类的一个实例,可以将这个公共基类说明为虚基类。 class 派生类名:virtual 继承方式 基类名
virtual是关键字,声明该基类为派生类的虚基类。
例如:
class 派生类: virtual 基类1,virtual 基类2,...,virtual 基类n { ...//派生类成员声明 };
在多继承情况下,虚基类关键字的作用范围和继承方式关键字相同,只对紧跟其后的基类起作用。 声明了虚基类之后,虚基类在进一步派生过程中始终和派生类一起,维护同一个基类子对象的拷贝。C++使用虚拟继承(Virtual Inheritance),解决从不同途径继承来的同名的数据成员在内存中有不同的拷贝造成数据不一致问题,将共同基类设置为虚基类。这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数名也只有一个映射。这样带来的有点是解决了二义性问题,也节省了内存,避免了数据不一致的问题。
3.用例
二义性:
#includeusing namespace std; //Base class Base { public: Base(){cout << "Base called..."<< endl;} void print(){cout << "Base print..." < 多重继承:
//说明:C++虚拟继承学习演示 //环境:VS2005 //blog:pppboy.blog.163.com //---------------------------------------------------- #include "stdafx.h" #includeusing namespace std; int gFlag = 0; class Base { public: Base(){cout << "Base called : " << gFlag++ << endl;} void print(){cout << "Base print" < output:
Base called : 0Mid1 calledBase called : 1Mid2 calledChild calledBase printBase print虚拟继承:
#include "stdafx.h" #includeusing namespace std; int gFlag = 0; class Base { public: Base(){cout << "Base called : " << gFlag++ << endl;} void print(){cout << "Base print" <
4.总结
在多继承情况下,虚基类关键字的作用范围和继承方式关键字相同,只对紧跟其后的基类起作用。声明了虚基类之后,虚基类在进一步派生过程中始终和派生类一起,维护同一个基类子对象的拷贝。观察类构造函数的构造顺序,拷贝也只有一份。
5.扩展
windows编程的程序员们在进行COM编程的时候会遇到这样的一个问题------继承接口IUnknown这一块使用非虚拟继承。这是为什么呢?如果有这样的疑问是很正常。之所以这样是由于会导致与COM不兼容的vtbl。比如:
struct IX : public IUnknown
{
//....
};
struct IY : public IUnknow
{
//....
};
客户程序实现:
... if(iid == IID_IUnknown) { //the client wants the IUnknown interface. *ppv = static_cast(this); } else if(iid == IID_IX){ //the client wants the IX interface. *ppv = static_cast (this); } else if(iid == IID_IY) { *ppv = static_cast (this); } ... 可见,程序中他们是通过类型转换的。不然,IX和IY的vtbl中的头三个函数指向的将不是IUnknown的三个成员函数。
当前标题:C++虚继承解说
链接URL:http://njwzjz.com/article/ipjopj.html