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虚继承,只有一个是虚继承仍然会有歧义

  • 相关阅读:
    windows下部署MySQL 8.0.11
    基于beego构建Restful API服务
    Go 并发
    Go语言的面向对象(OOP)
    Go基础语法纪要
    软件工程基础图式(第四章 系统设计-面向过程的系统设计)
    概率论与数理统计图式(第三章 多维随机变量)
    编译技术图式(第四章 语法分析)01文法和语法的定义
    计算机组成原理和结构图式(第三章 CPU子系统)
    Java图式(第三章 流程控制、数组)
  • 原文地址:https://www.cnblogs.com/yuzaipiaofei/p/4124480.html
Copyright © 2011-2022 走看看