从具有相同成员的父母那里继承遗产

2022-08-24 00:00:00 inheritance multiple-inheritance c++

我在访问多重继承下的父级成员(同名)时遇到问题。我有4类(经典钻石问题)定义如下:

class ClapTrap
{
    public:
        ClapTrap(void)
        { _hitpoints = 0; }
        ~ClapTrap() { }

    protected:
        int             _hitpoints;
};

class ScravTrap : public virtual ClapTrap
{
    public:
        ScravTrap(void)
        { _hitpoints = 1; }
        ~ScravTrap() { }
};

class FragTrap : public virtual ClapTrap
{
    public:
        FragTrap(void)
        { _hitpoints = 2; }
        ~FragTrap() { }
};

class DiamondTrap : public ScravTrap, public FragTrap
{
    public:
        DiamondTrap(void)
        { 
            std::cout << ScravTrap::_hitpoints << std::endl;
            std::cout << FragTrap::_hitpoints << std::endl;
        }
        ~DiamondTrap() { }
};


int main()
{
    DiamondTrap d;
}

Main的输出为

2
2

我预计此输出为

1
2

因为我第一次打印DiamondTrap的SCravTrap::_HitPoints成员(ScrapTrap::_HitPoints初始化为1),第二次打印DiamondTrap的FragTrap::_HitPoints成员(之前已初始化为2)。我知道DiamondTrap继承了这两个_Hitpoint成员,但如何正确访问它们?

注意即使我在DiamondTrap类的公共部分的开头写了using ScravTrap::_hitpoints,输出仍然是一样的。为什么会发生这种情况?

编辑有些答案提到虚拟继承只生成基类的一个副本。在创建DiamondTrap的实例时,我只想调用一次claptrap的构造函数。我如何才能做到这一点,同时还可以访问SCravTrap::_HitPoints和FragTrap::_Hitpoint?如果我在每个父类中都有两个成员,该怎么办?DiamondTrap可以继承Fragtrap的其中一个和SCravTrap的一个吗?我该怎么做?


解决方案

由于您使用了virtual继承,因此只有一个ClapTrap,并且只有一个_hitpoints

不能让_hitpoints变量携带多个值。

首先构造ClapTrap,赋值0,然后构造ScravTrap,赋值1,最后构造FragTrap,将2-all赋给同一个_hitpoints变量。

创建DiamondTrap的实例时,我只想调用ClapTrap的构造函数一次。

这就是您现在要做的。

如何既可以执行此操作,又可以同时访问ScravTrap::_hitpointsFragTrap::_hitpoints

您不能。您必须选择其中一个。

如果没有virtual继承,您将有两个构造函数调用和ScravTrap::_hitpointsFragTrap::_hitpoints

使用virtual继承,您将有一个构造函数调用,并且只有一个_hitpoints

相关文章