ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【Example】C++ 虚基类与虚继承 (菱形继承问题)

2022-02-25 01:31:50  阅读:193  来源: 互联网

标签:Expert 继承 C++ class Base 基类 Byte public


C++ 是支持多继承的语言,但是实际项目开发中非必要不要使用多继承以降低代码逻辑的复杂性,当然 C++ 多继承的特性带来一些问题即菱形继承。

当一个类继承了两个来自同父类的子类后,会产生命名空间冲突及资源冗余。

 

【伪代码】

class Base{
public:
    int gem = 0; 
};

class Byte : public Base{};

class Expert : public Base{};

class Blu : public Byte, public Expert{
public:

    // Error 字段不明确
    void SetGem(int i) {
        this->gem = i;
    }

}

 

可以看到,产生错误的主要原因是,Byte 和 Expert 同样都继承了 Base,然后 Blu 又继承了 Byte 和 Expert 。

根据 C++ 类继承的机制,子类的大小=父类大小+子类自身成员大小。

因此,可以看出,实际上 Blu 类当中存在两个 Gem 成员变量,分别来自 Byte 和 Expert,使用 this 指针进行调用,会发生命名空间冲突错误,同时造成了资源的重复浪费

解决的方法也很简单,使用虚继承的方式:

 

【伪代码】

class Base{};

class Byte : virtual public Base{}; 

class Expert : virtual public Base{};

 

可以看到,在 Byte 和 Expert 的继承后面使用了 virtual 关键字进行了修饰。

这时,Base 便成了 Byte 和 Expert 的虚基类,达成了虚继承的方式,Base 类在最终的 Blu 类中只存在一个,所以不存在命名空间冲突及资源浪费。

虚基类并不是“绝对的”,而是“相对的”:虚基类在它自身声明、定义的时候无需任何修饰,只是在子类继承时进行 virtual 修饰。

 

然而这又牵扯到了另一种错误:

【伪代码】

class Base{};

class Byte : virtual public Base{}; 

class Expert : virtual public Base{};

class Frog : public Base{};

class Blu : public Byte, public Expert, public Frog{};

 

可以看到,Blu 继承了 Byte 、Expert、Frog 三个类,但是 Frog 类不是以虚继承的方式继承 Base 的。

所以在 Blu 类中仍然存在菱形继承的问题,所有需要将所有继承同一基类的上级父类继承方式声明为 virtual。

同时,在虚继承机制当中,虚基类是由最终的派生类进行初始化的,本身达成了一种 “间接继承” 的关系。

也就意味着最终的派生类在构造函数初始化中,要在初始化表中调用虚基类的构造函数进行初始化。

这样,就保证了虚基类不会被二次初始化。

 

最终正确代码是这样的:

class Base {
public:
    Base() {};
    ~Base() {};

public:
    int gem = 1;
};

class Byte : virtual public Base
{
public:
    Byte() {};
    ~Byte() {};

};

class Expert : virtual public Base
{
public:
    Expert() {};
    ~Expert() {};

};

class Blu : public Byte, public Expert
{
public:
    // 调用虚基类构造函数
    Blu() : Base(),Byte(),Expert() {};
    ~Blu() {};

    void SetGem(int i) {
        this->gem = i;
    }
};

 

标签:Expert,继承,C++,class,Base,基类,Byte,public
来源: https://www.cnblogs.com/airchip/p/15934234.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有