C++面向对象--第十一章菱形继承和二义性问题

菱形继承

菱形继承(Diamond Inheritance)是指一个派生类同时继承自两个直接或间接基类,而这两个基类又共同继承自同一基类的情况。这种继承关系形成了类似于菱形的结构,因此称为菱形继承。

        

        图中,Animal是基类,Mammal和Bird是它的派生类,而Bat则同时从Mammal和Bird派生,形成了菱形继承。

虚基类

当一个类被声明为虚基类时,它的派生类只会保留一个对该虚基类的引用,从而解决了多次继承带来的二义性和冲突问题。

其中,这个被共享的基类就称为虚基类(Virtual Base Class)。派生类的同名成员比虚基类的优先级更高

二义性的解决方法

1.加作用域

例:

        

class Animal

{

public:

    int data;

};



class Sheep:public Animal

{

public:

};



class Tuo:public Animal

{

public:

};



class SheepTuo:public Sheep,public Tuo

{

public:

};



int main()

{

    SheepTuo test;

    //test.data=100;//报错,test中有两个a

    //解决方式1:加作用域

    test.Sheep::data=100;

    test.Tuo::data=100;

    return 0;

}

深入研究(VS studio)

        Animal类

                

        Sheep类

                

        Tuo类

                

        SheepTuo类

                

2.虚继承

声明:

        

例:

class Animal

{

public:

    int data;

};



class Sheep:virtual public Animal

{

public:

};



class Tuo:virtual public Animal

{

public:

};



class SheepTuo:public Sheep,public Tuo

{

public:

};



int main()

{

    SheepTuo test;

    test.data=100;

    return 0;

}

深入研究(VS studio)

        Animal类

                

        Sheep类

               

                vbptr(虚基类指针):v是virtual,b是base,ptr是指针。指向虚基类表

                vbtable(虚基类表):保存了当前的虚指针相对于虚基类的首地址的偏移量(即子类中从父类继承的数据相对父类的偏移量)--从此,继承的不再是数据,而是指针和虚基类表

                总结:之所以产生vbptr和vbtable目的保证不管多少个继承虚基类的数据只有一份。

        Tuo类

                

        SheepTuo类

                                

                

                根据不同的虚基类表,可以定位到相同的数据

                1.vbtable@Sheep@:偏移量是8;sheep的指针指向0,偏移8,正好是data

                2.vbtable@Tuo@:偏移量是4;sheep的指针指向4,偏移4,正好也是data

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中的类继承和派生是面向对象编程中的重要概念。在C++中,可以使用公有继承、保护继承和私有继承来实现类的继承和派生。 公有继承是最常见的一种继承方式,它可以使得基类的公有成员在派生类中仍然是公有的,保护成员在派生类中变为保护的,私有成员在派生类中不可访问。\[1\] 保护继承是一种特殊的继承方式,它可以使得基类的公有和保护成员在派生类中变为保护的,私有成员在派生类中不可访问。\[2\] 私有继承是一种特殊的继承方式,它可以使得基类的公有和保护成员在派生类中变为私有的,私有成员在派生类中不可访问。私有继承主要用于实现"实现继承",即派生类通过继承基类的实现来实现自己的功能。\[3\] 在派生类中,可以使用基类的成员函数和成员变量,但是访问权限受到继承方式的限制。公有继承和保护继承可以访问基类的成员函数和成员变量,私有继承只能在派生类内部访问基类的成员函数和成员变量。 总结起来,C++中的类继承和派生可以通过公有继承、保护继承和私有继承来实现,不同的继承方式决定了派生类对基类成员的访问权限。 #### 引用[.reference_title] - *1* *2* [C++ 面向对象 - 类的继承与派生](https://blog.csdn.net/m0_62598965/article/details/124610795)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [C++面向对象-继承和派生](https://blog.csdn.net/D23333A/article/details/116640148)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值