<十>关于菱形继承
2023-02-18 16:33:45 时间
代码1
#include <iostream>
using namespace std;
class A{
public:
A(int _a):ma(_a){
cout<<"A()"<<endl;
}
~A(){
cout<<"~A()"<<endl;
}
protected:
int ma;
};
class B : public A{
public:
B(int _b):A(_b),mb(_b){
cout<<"B()"<<endl;
}
~B(){
cout<<"~B()"<<endl;
}
protected:
int mb;
};
class C : public A{
public:
C(int _c):A(_c),mc(_c){
cout<<"C()"<<endl;
}
~C(){
cout<<"~C()"<<endl;
}
protected:
int mc;
};
class D : public B, C{
public:
D(int _d):B(_d),C(_d),md(_d){
cout<<"D()"<<endl;
}
~D(){
cout<<"~D()"<<endl;
}
protected:
int md;
};
int main(){
D d(100);
return 0;
}
//代码执行顺序
A()
B()
A()
C()
D()
~D()
~C()
~A()
~B()
~A()
D的内存结构
发现有重复的 数据 ma
为了解决上面的问题,引入虚继承
代码2
#include <iostream>
using namespace std;
class A{
public:
A(int _a):ma(_a){
cout<<"A()"<<endl;
}
~A(){
cout<<"~A()"<<endl;
}
protected:
int ma;
};
class B : virtual public A{
public:
B(int _b):A(_b),mb(_b){
cout<<"B()"<<endl;
}
~B(){
cout<<"~B()"<<endl;
}
protected:
int mb;
};
class C : virtual public A{
public:
C(int _c):A(_c),mc(_c){
cout<<"C()"<<endl;
}
~C(){
cout<<"~C()"<<endl;
}
protected:
int mc;
};
class D : public B, C{
public:
D(int _d):A(_d),B(_d),C(_d),md(_d){
cout<<"D()"<<endl;
}
~D(){
cout<<"~D()"<<endl;
}
protected:
int md;
};
int main(){
D d(100);
return 0;
}
//执行结果
A()
B()
C()
D()
~D()
~C()
~B()
~A()
//A的构造有D 来完成 B和C下面有各自的vbptr 定位得基类数据
虚继承用来解决多重继承中遇到的多份数据的问题
虚拟继承在一般的应用中很少用到,所以也往往被忽视,这也主要是因为在C++中,多重继承是不推荐的,也并不常用,而一旦离开了多重继承,虚拟继承就完全失去了存在的必要(因为这样只会降低效率和占用更多的空间,关于这一点,我自己还没有太多深刻的理解,有兴趣的可以看网络上白杨的作品《RTTI、虚函数和虚基类的开销分析及使用指导》)。
相关文章
- Grafana 系列文章(一):基于 Grafana 的全栈可观察性 Demo
- Docker 基础 - 3
- Docker 基础 - 2
- Docker 基础 - 1
- Crossplane - 比 Terraform 更先进的云基础架构管理平台?
- Cert Manager 申请SSL证书流程及相关概念-三
- Cert Manager 申请SSL证书流程及相关概念-二
- Cert Manager 申请 SSL 证书流程及相关概念 - 一
- APM vs NPM
- API 网关的功能用途及实现方式
- Ansible 学习笔记 - 批量巡检站点 URL 状态
- Ansible 学习笔记 - 定位主机和组的模式
- 制作容器镜像的最佳实践
- 在 NGINX 中根据用户真实 IP 进行限制
- 在 K8S Volume 中使用 subPath
- 我的基于 JamStack 的新博客
- 使用Prometheus监控docker compose方式部署的ES
- 使用 K8S 部署 RSS 全套自托管解决方案- RssHub + Tiny Tiny Rss
- 使用Jiralert实现AlertManager告警对接Jira
- 使用 Helm 安装 MQTT 服务器-EMQX