C++虚继承解说-创新互联

1.概括

专注于为中小企业提供网站建设、成都网站制作服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业涟水免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了上千家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。

    在CPlusPlus多继承编程中时常遇到这样一个问题--若子类实现多个基类或接口继承,多基类或接口中存在成员名相同,在客户与实现类之间的通信时编译器报错“不能这样使用,会产生二义性”由于这个问题的解决方法很多。比如说,可以把相同的成员名给改过来。但是,从专业的角度,可能虚拟继承会解决这个问题。那接下来我看看c++是怎么避免这种问题的。

2.概念

    当在多条继承路径上有一个公共的基类,在这些路径中的某几条汇合处,这个公共的基类就会产生多个实例(或多个副本),若只想保存这个基类的一个实例,可以将这个公共基类说明为虚基类。      class 派生类名:virtual 继承方式  基类名

    virtual是关键字,声明该基类为派生类的虚基类。

    例如:

    class 派生类: virtual 基类1,virtual 基类2,...,virtual 基类n
    
    {
        
        ...//派生类成员声明
    
    };

    在多继承情况下,虚基类关键字的作用范围和继承方式关键字相同,只对紧跟其后的基类起作用。 声明了虚基类之后,虚基类在进一步派生过程中始终和派生类一起,维护同一个基类子对象的拷贝。C++使用虚拟继承(Virtual Inheritance),解决从不同途径继承来的同名的数据成员在内存中有不同的拷贝造成数据不一致问题,将共同基类设置为虚基类。这时从不同的路径继承过来的同名数据成员在内存中就只有一个拷贝,同一个函数名也只有一个映射。这样带来的有点是解决了二义性问题,也节省了内存,避免了数据不一致的问题。

3.用例

二义性:

#include 
using 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"  
#include 
using namespace std;  
int gFlag = 0;  
class Base  
{
public:  
 Base(){cout << "Base called : " << gFlag++ << endl;}  
 void print(){cout << "Base print" <

output:

Base called : 0
 Mid1 called
 Base called : 1
 Mid2 called
 Child called
 Base print
 Base print

虚拟继承:

#include "stdafx.h"  
#include 
using 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的三个成员函数。

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


网站名称:C++虚继承解说-创新互联
文章起源:http://scyanting.com/article/dihsdc.html