zoukankan      html  css  js  c++  java
  • 虚继承

     

    虚继承

    原帖地址:http://blog.myspace.cn/e/400067548.htm

    以下都是我个人的理解,估计有问题,看的时候请慎重考虑,仔细判断

    1.被虚继承的类就是虚基类
    2.何为虚继承: 先说普通继承
    普通继承: class B: public A, 
    B从A继承,B会将A做一份copy,作为自身的一部分,然后在加自己独有的一部分。
    加入A是一个有虚函数的类,考虑A和B的结构
    sizeof(A) = sizeof(A的数据成员) + sizeof(vptr),这个vptr指向A类的 vtable
    sizeof(B) = sizof(A的数据成员) + sizeof(B数据成员) + sizeof(vptr),这个vptr指向B类的vtable

    虚继承: 虚继承与普通继承不同点在于,子类不实际的copy父类的一部分,而是生成一个引用,指向父类对象
    但是在用sizeof统计大小时,依然将父类的成员变量统计在内,此时B的结构如下:
    sizeof(B) = sizof(A的数据成员) + sizeof(B数据成员) + sizeof(vptr) + sizeof(pointer to A), vptr指向B类的vtable, 并且多了一个引用指向A对象

    虚继承的这个特性在C++的多重继承应用中可以起到很好的作用:
    一个没有虚继承的多重继承:
    class A
    {
     void f() ;
    };
    class B: public A
    {
    };
    class C:public A
    {
    }
    class D: public B, public C
    {
    }
    void main()
    {
     D d;
    d.f();
    }
    这种情况下编译器会报错:D::f is ambiguous,could be the 'f' in base 'A' of base 'B' of class 'D',or the 'f' in base 'A' of base 'C' of class 'D'
    很明显看出:d.f()是有歧义的,因为D中有2个A的copy,也就有2个A::f()函数,编译器不知道应该调用哪一个。

    这个问题应用虚继承可以得到很好的解决,类定义重写如下:
    class A
    {
     void f() ;
    };
    class B: public virtual A
    {
    };
    class C:public virtual A
    {
    }
    class D: public B, public C
    {
    }
    void main()
    {
     D d;
    d.f();
    }
    此时D中只指向一个A对象,调用d.f(),就是调用那个唯一的A的f()函数,没有歧义,顺利执行。因为此时B和C都是指向同一个A对象。
    此时D的结构如下图:

    需要注意的是B和C都必须是从A虚继承,只有一个是虚继承仍然会有歧义

  • 相关阅读:
    Ubuntu 制作run安装包 依赖mono开发的软件 半自动安装包
    Windows C# to Linux Mono
    Ubuntu 18.04 操作简记
    Ubuntu 安装 Qt 简记
    Visual Studio操作记录
    WinForm项目中使用Xaml资源字典
    加载大量控件
    executable file and DLL
    微信小程序IOS系统兼容 Date.parse() 时间字符串转时间戳
    谷歌浏览器禁用 页面js
  • 原文地址:https://www.cnblogs.com/yuzaipiaofei/p/4124480.html
Copyright © 2011-2022 走看看