如何从钻石继承中的不同类别中获取值

Posted

技术标签:

【中文标题】如何从钻石继承中的不同类别中获取值【英文标题】:How to take values from different classes in diamond-inheritance 【发布时间】:2021-12-01 09:36:19 【问题描述】:
#include <iostream>

class A

    protected:
        std::string _name;
        int _points;
        int _energy;
    
    public:

        A(std::string name, int points, int energy) : _name(name), _points(points), _energy(energy)
                    
        
        A(std::string name) : _name(name), _points(10), _energy(10)
        
        
;

class B : public virtual A

    public:

        B(std::string name): A(name, 20, 20)
        
        
;

class C : public virtual A

    public:

        C(std::string name) : A(name, 30, 30)
        
        
;

class D : public B, public C

    private:

            std::string _name_d;

    public:

        D(std::string name): A(name), B(name), C(name), _name_d(name)
        
            A::_name = "another name";
            _points = B::_points;
            _energy = C::_energy;
            std::cout << "name class D   " << _name_d << std::endl;
            std::cout << "name class A   " << A::_name << std::endl;
            std::cout << "energy class D " << _energy << std::endl;
            std::cout << "points class D " << _points << std::endl;
        
;

int main(void)

    D d("Bill");
    return (0);

这是我的第一个 Diamond 继承代码。在 C 类上,我需要从 B 类中获取 _points 的值,从 C 类中获取 _energy 的值,但接下来是输出:

name class D   Bill
name class A   another name
energy class D 10
points class D 10

我该如何解决这个问题?

【问题讨论】:

听起来您不想使用虚拟继承,那么,如果您希望D 实例的BC 子对象具有不同的底层A 子子对象. 通常应该避免多重继承,甚至更多地使用菱形继承或虚拟继承......它会使代码更难维护。事实上,很多语言不支持多重继承(或者只支持接口)。 【参考方案1】:

首先要注意的是,无论你使用哪个前缀,成员变量都是同一个对象。我的意思是:

    A::_nameB::_nameC::_nameD::_name 相同 A::_pointsB::_pointsC::_pointsD::_points 相同 等

第一个被调用的构造函数是来自虚拟基类的构造函数,然后是中间类,最后是派生类。

中间类对基类的构造没有影响。

所以你得到的输出非常好:字段_name_d 仅属于类D,但其他三个在四个类中可用,因为它们是在基虚拟类中声明的。

如果您打算拥有B::_points = 20C::_points = 30,那么您将不得不创建更多对象,因为D 类型的任何对象都会将它们设置为10

再次重申:您只有一个对象,并且只有一个 _name_points_energy

【讨论】:

以上是关于如何从钻石继承中的不同类别中获取值的主要内容,如果未能解决你的问题,请参考以下文章

钻石(菱形)继承和虚基类

如何获取同一张表中不同类别的布尔值的比例

如何从表中的每个不同类别中选择三行?

如何根据类别从数据库中选择不同的数据

从适配器类获取不同活动中的 EditText 值

从 Cassandra 列族中的冻结集列中获取不同的字段值