从具有相同成员的 parents 继承

Inheritance from parents with same members

我无法访问多重继承下 parent 的成员(同名)。我有4个classes(classic钻石问题)定义如下:

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;
}

我的主要输出是

2
2

我预计这个输出是

1
2

因为我第一次打印 DiamondTrap 的 ScravTrap::_hitpoints 成员(并且 ScrapTrap::_hitpoints 被初始化为 1),第二次我打印 DiamondTrap 的 FragTrap::_hitpoints 成员(之前已初始化为 2)。我知道 DiamondTrap 继承了两个 _hitpoint 成员,但我怎样才能正确访问它们?

注意 即使我在 DiamondTrap class 的 public 部分的开头写了 using ScravTrap::_hitpoints,输出仍然是相同的。为什么会这样?

编辑 一些答案提到虚拟继承只生成一个基础副本class。我只想在创建 DiamondTrap 实例时调用 ClapTrap 的构造函数一次。我怎样才能做到这一点并同时访问 ScravTrap::_hitpoints 和 FragTrap::_hitpoints?如果我在每个 parent class 中有两个成员怎么办? DiamondTrap 能否从 FragTrap 继承其中一个,从 ScravTrap 继承其中一个?我该怎么做?

只有 一个 ClapTrap 因为你使用 virtual 继承,所以只有一个 _hitpoints.

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

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

I want to call the constructor of ClapTrap only once when creating an instance of DiamondTrap.

这就是你现在所做的。

How can I do this and also have access to both ScravTrap::_hitpoints and FragTrap::_hitpoints?

你不能。你必须select其中之一。

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

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

I expected this output to be

1
2

一个int对象不能同时有两个不同的值,所以这个输出是不可能的。

know that DiamondTrap inherits both _hitpoint members

只有一个 ClapTrap,因此只有一个 _hitpoint 成员。

Why is this happening?

发生这种情况是因为您使用了虚拟继承。 _hitpoints 首先在虚拟基础 ClapTrap 的构造函数中用不确定的值初始化,然后将其分配给 0。之后,基础 ScravTrap 的构造函数将其分配给 1 最后, base FragTrap 的构造函数将其分配给 2.

want to call the constructor of ClapTrap only once when creating an instance of DiamondTrap. How can I do this and also have access to both ScravTrap::_hitpoints and FragTrap::_hitpoints?

ClapTrap 中删除成员并将成员添加到 ScravTrapFragTrap 将实现您想要的。不清楚你为什么要这个。