虚继承

17 篇文章 1 订阅
1.菱形继承:

  1>继承模型:


  2>代码测试并查看内存模型

#include<iostream>
using namespace std;
class A
{
public:
    A(int a = 5)
       :_a(a)
    {
       cout<<"A的构造被调用"<<endl;
    }
    ~A()
    {
       cout<<"A被析构"<<endl;
    }
private:
    int _a;
};
class B:public A
{
public:
    B(int b = 0)
       :_b(b)
    {
       cout<<"B的构造被调用"<<endl;
    }
    ~B()
    {
       cout<<"B被析构"<<endl;
    }
private:
    int _b;
};
class C:public A
{
public:
    C(int c = 0)
       :_c(c)
    {
       cout<<"C的构造被调用"<<endl;
    }
    ~C()
    {
       cout<<"C被析构"<<endl;
    }
private:
    int _c;
};
class D:public B,public C
{
public:
    D(int d = 0)
       :_d(d)
    {
       cout<<"D的构造被调用"<<endl;
    }
    ~D()
    {
       cout<<"D被析构"<<endl;
    }
private:
    int _d;
};
void Test()
{
    B b(10);
    C c(20);
    D d(30);
    cout<<"A类的大小是:"<<sizeof(A)<<endl;
    cout<<"B类的大小是:"<<sizeof(B)<<endl;
    cout<<"C类的大小是:"<<sizeof(C)<<endl;
    cout<<"D类的大小是:"<<sizeof(D)<<endl;
}
程序运行结果及分析:


内存分布图:



从内存分布图和程序的运行结果我们可以看出,在D类的对象d中,存在A类的对象成员的两份,就存在数据冗余的现象。如果我们想要查看d对象中的_a成员(由于没有给出其他的公有成员函数,这里只能将_a先设为public来测试),程序就会出现这样的情况。


所以,菱形继承不仅仅存在数据冗余的问题,还存在二义性的问题,那么在这里,我们如何处理这个二义性的问题?
处理办法:加上类的作用域限定符。
如图:

当然,这样的办法虽然可以解决二义性的问题,仍然不能解决数据冗余的问题。
2.虚继承
虚继承就是来解决菱形继承中出现的两个问题。
1>继承模型:

2>代码测试并查看内存模型:
代码:在上边的代码的基础上进行修改:
将B和C的继承都变成虚继承,对应修改成以下的两行代码:
class B:virtual public A
class C:virtual public A
运行结果:



内存分布图:



关于虚继承,就先整理到这里,之后还会涉及到含有虚函数的虚继承,其中必然包含虚表,所以,涉及到虚继承(与虚基表有关),并不一定和虚表有关。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值