C++虚基类图解

虚继承:在继承定义中包含了virtual关键字的继承关系;
虚基类:被虚继承的类,是相对概念;
例:people是student的虚基类
虚基类的出现时为了解决二义性问题,使派生类中只保留一份拷贝

经典菱形继承

在这里插入图片描述
student是people子类,teacher是people子类,doctor同时继承student和teacher
一般情况下,student和teacher中分别包含people的空间 ,doctor会直接继承两边people的空间,形成空间冗余
C++提供虚基类(virtual base class )的方法,使得在继承间接共同基类时只保留一份成员。
即在继承的同时加virtual 节省多余的空间,避免出现基类的多次继承

图解

在这里插入图片描述
①普通继承:
dortor的大小为(student属性)12+(teacher属性)12+(doctor属性)4=28
(保留两个people空间,出现空间冗余)
②生成一个student的虚基类:
dortor的大小为(student属性)12+(student的虚基类指针)4+(teacher属性)12+(doctor属性)4=32
③虚基类:
dortor的大小为(student属性)12+(student的虚基类指针)4+(teacher属性)12+(teacher的虚基类指针)4+(doctor属性)4-(people属性)8=28

声明方式

关键字 virtual

一般形式为
class 派生类名:virtual 继承方式 基类名
经过这样的声明后,当基类通过多条派生路径被一个派生类继承时,该派生类只继承该基类一次。
如果基类的全部派生类没有都使用虚基类的话,还是会出现多次继承。

代码实现

简易版abcd

#include<iostream>
using namespace std;
class A
{
protected:
        A(int q):a(q){}
        int a;
};
class B:virtual protected A
{
protected:
        B(int w,int a):b(w),A(a){}
        int b;
};
class C:virtual protected A
{
protected:
        C(int e,int a):c(e),A(a){}
        int c;
};
class D:protected B,protected C
{
protected:
        int d;
public:
        D(int q,int w,int e,int r):A(q),B(w,0),C(e,0),d(r){}
        void showd()
        {
        cout<<a<<endl;
        cout<<b<<endl;
        cout<<c<<endl;
        cout<<d<<endl;
        }
};
int main()
{
        D d(1,2,3,4);
        d.showd();
        return 0;
}           

人类学生老师版

#include<iostream>
using namespace std;
//people
class people
{
public:
        people()
        {
                name="\0";
                id=0;
        }
        people(string n,int i):name(n),id(i)
        {
        }
        void show()
        {
        cout<<name<<" "<<id<<" "<<endl;
        }
protected:
        string name;
        int id;
};
//student
class student:virtual public people
{
public:
        student(string n,int i,int s):people(n,i),score(s)
        {
        }
        void shows()
        {
        //show();
        cout<<score<<" "<<endl;
        }
protected:
        int score;
};
//teacher
class teacher:virtual public people
{
public:
        teacher(string n,int i,int g):people(n,i),grade(g)
        {
        }
        void showt()
        {
        //show();
        cout<<grade<<" "<<endl;
        }
protected:
        int grade;
};
//docter
class doctor:public student,public teacher
{
public:
        doctor(string n,int i,int s,int g,string sch):people(n,i),student("",0,s),teacher("",0,g),school(sch)
        {
        }
        void showd()
        {
        show();
        shows();
        showt();
        cout<<school<<" "<<endl;
        }
protected:
        string school;
};
//main
int main()
{
        doctor d("lc",1001,100,17,"sy");
        d.showd();
        cout<<sizeof(people)<<endl;
        cout<<sizeof(student)<<endl;
        cout<<sizeof(teacher)<<endl;
        cout<<sizeof(doctor)<<endl;
        return 0;
}

代码输出为


lc 1001
100
17
sy
8
16
16
28

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值