• 虚继承实现原理(虚基类表指针与虚基类表)


    虚继承和虚函数是完全无相关的两个概念。

    虚继承是解决C++多重继承问题的一种手段,从不同途径继承来的同一基类,会在子类中存在多份拷贝。这将存在两个问题:其一,浪费存储空间;第二,存在二义性问题,通常可以将派生类对象的地址赋值给基类对象,实现的具体方式是,将基类指针指向继承类(继承类有基类的拷贝)中的基类对象的地址,但是多重继承可能存在一个基类的多份拷贝,这就出现了二义性。

    虚继承可以解决多种继承前面提到的两个问题:

    虚继承底层实现原理与编译器相关,一般通过虚基类指针和虚基类表实现,每个虚继承的子类都有一个虚基类指针(占用一个指针的存储空间,4字节)和虚基类表(不占用类对象的存储空间)(需要强调的是,虚基类依旧会在子类里面存在拷贝,只是仅仅最多存在一份而已,并不是不在子类里面了);当虚继承的子类被当做父类继承时,虚基类指针也会被继承。

    实际上,vbptr指的是虚基类表指针(virtual base table pointer),该指针指向了一个虚基类表(virtual table),虚表中记录了虚基类与本类的偏移地址;通过偏移地址,这样就找到了虚基类成员,而虚继承也不用像普通多继承那样维持着公共基类(虚基类)的两份同样的拷贝,节省了存储空间。

    在这里我们可以对比虚函数的实现原理:他们有相似之处,都利用了虚指针(均占用类的存储空间)和虚表(均不占用类的存储空间)。

    虚基类依旧存在继承类中,只占用存储空间;虚函数不占用存储空间。

    虚基类表存储的是虚基类相对直接继承类的偏移;而虚函数表存储的是虚函数地址。

    
        #include<iostream>  
        using namespace std;  
          
        class A  //大小为4  
        {  
        public:  
            int a;  
        };  
        class B :virtual public A  //大小为12,变量a,b共8字节,虚基类表指针4  
        {  
        public:  
            int b;  
        };  
        class C :virtual public A //与B一样12  
        {  
        public:  
            int c;  
        };  
        class D :public B, public C //24,变量a,b,c,d共16,B的虚基类指针4,C的虚基类指针  
        {  
        public:  
            int d;  
        };  
          
        int main()  
        {  
            A a;  
            B b;  
            C c;  
            D d;  
            cout << sizeof(a) << endl;  
            cout << sizeof(b) << endl;  
            cout << sizeof(c) << endl;  
            cout << sizeof(d) << endl;  
            system("pause");  
            return 0;  
    }
    
  • 相关阅读:
    linux下查看当前登陆的用户数目
    uboot能ping通本机无法ping通本机上搭建的虚拟机
    一个时序图描述从用户在浏览器地址栏输入url并按回车,到浏览器显示相关内容的各个过程
    3*0.1 == 0.3 将会返回什么?true 还是 false?
    Floating Point Math
    浮点数在计算机中是如何表示的
    浮点数在计算机中是如何表示的
    Java并发编程:volatile关键字解析
    join的源码
    i++ 是线程安全的吗
  • 原文地址:https://www.cnblogs.com/hunter-w/p/13845899.html
Copyright © 2020-2023  润新知