C++:菱形继承与虚继承

看下面这个示例代码

class A{
public:
int num=10;
A(){cout<<"A构造"<<endl;}
virtual void fun(){cout<<"A虚函数"<<endl;}
};

class B:public A{
public:
B(){cout<<"B构造"<<endl;}
void fun(){cout<<"B虚函数"<<endl;}
};

class C:public A{
public:
C(){cout<<"C构造"<<endl;}
void fun(){cout<<"C虚函数"<<endl;}
};

class D:public C,public B{
public:
D(){cout<<"D构造"<<endl;}
void fun(){cout<<"D虚函数"<<num<<endl;}
};

这段代码你会发现这段代码编译不通过,因为D类的虚函数在访问num时不知道访问哪个,将这个虚函数里面的内容清空然后执行会得到以下结果:
在这里插入图片描述

可以看到D多次继承了同一个基类,这样就造成了构造D时构造了多个A,问题本身没有什么影响但是如果D需要访问A中的东西时就会有两个渠道,通过B或者C,这时候加上作用域的话就可以运行了,但是这样太麻烦了,而且对共同的基类A真的没必要构造两次,为了处理这种情况引入了虚继承的概念。
之前介绍过虚函数,虚继承和它类似

  • 发生虚继承的时候就会产生一个虚基表和相应的虚基表指针
  • 虚基表是静态的,这点和虚函数表差不多
  • 发生虚继承后对任意类只会创建一次
  • 虚基表存储虚基表指针到其基类的偏移量
  • 一个类只会有一个虚基表,但是可以有多个虚基表指针

这些概念后面梳理,现在先看修改后的代码

class A{
public:
int num=10;
A(){cout<<"A构造"<<endl;}
virtual void fun(){cout<<"A虚函数"<<endl;}
};
class B:virtual public A{
public:
B(){cout<<"B构造"<<endl;}
void fun(){cout<<"B虚函数"<<endl;}
};
class C:virtual public A{
public:
C(){cout<<"C构造"<<endl;}
void fun(){cout<<"C虚函数"<<endl;}
};
class D:virtual public C,virtual public B{
public:
D(){cout<<"D构造"<<endl;}
void fun(){cout<<"D虚函数"<<num<<endl;}
};

看看执行结果
在这里插入图片描述
可以看出问题被解决了,接下来看它在内存中的分布
在vs开发者命令行模式下输入下面的指令即可

cl /d1 reportSingleClassLayoutXXX 文件名.cpp

xxx替换为自己的类名,我这里是D

在这里插入图片描述
可以看到类的结构还是很清晰的,每个使用虚继承的类头部都有一个虚基表指针,同时虚函数表指针不再出现在头部,不需要过多解释自己看吧
在这里插入图片描述
虚继承通过减少基类的重复创建解决了多次继承同一基类造成的二义性问题,借助虚基表完成了基类的定位,可以说很是牛皮,但是缺点也很明显它破坏了类中的原有布局,它使类中的内存分布情况程序多样化,现在虚函数表指针可能有多个甚至位置也会按照继承的顺序而改变,内存的分布依赖于代码书写,所以说要慎用,虽然我们不需要过多关注内存,但是对性能的影响却是真实存在的。

相关推荐

  1. C++——继承菱形继承

    2024-03-17 20:40:02       32 阅读
  2. C++继承

    2024-03-17 20:40:02       13 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-17 20:40:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-17 20:40:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-17 20:40:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-17 20:40:02       20 阅读

热门阅读

  1. pyqt生成.py文件和资源打包

    2024-03-17 20:40:02       19 阅读
  2. rsa数据加密无大小限制——golang实现

    2024-03-17 20:40:02       21 阅读
  3. 机器学习算法在数据挖掘中的应用

    2024-03-17 20:40:02       22 阅读
  4. 数字电子技术实验(六)

    2024-03-17 20:40:02       22 阅读
  5. 【C++】C++面向对象练习题

    2024-03-17 20:40:02       22 阅读
  6. 聊聊Python都能做些什么

    2024-03-17 20:40:02       18 阅读
  7. 用计算机处理数字——数值的类型

    2024-03-17 20:40:02       18 阅读
  8. mysql57开启biglog并查看biglog保姆级教程

    2024-03-17 20:40:02       22 阅读
  9. 鸿蒙开发 -- ui结构样式复用

    2024-03-17 20:40:02       22 阅读
  10. koa2+vue3通过exceljs实现数据导出excel文档

    2024-03-17 20:40:02       21 阅读
  11. IOS面试题object-c 146-150

    2024-03-17 20:40:02       20 阅读
  12. 循序渐进理解数据库基本概念

    2024-03-17 20:40:02       25 阅读
  13. 分布式微服务 - 总概

    2024-03-17 20:40:02       21 阅读