I am having trouble accessing members (with the same name) of parents under multiple inheritance. I have 4 classes (classic diamond problem) defined as follows:
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;
}
The output of my main is
2
2
I expected this output to be
1
2
because the first time I am printing the ScravTrap::_hitpoints member of DiamondTrap (and ScrapTrap::_hitpoints is initialized to 1) and the second time I am printing the FragTrap::_hitpoints member of DiamondTrap (which has previously been initialized to 2). I know that DiamondTrap inherits both _hitpoint members, but how can I access them properly?
NOTE Even if I write using ScravTrap::_hitpoints
at the beginning of the public part of my DiamondTrap class, the output is still the same. Why is this happening?
EDIT Some of the answers mention that virtual inheritance generates only one copy of the base class. 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? What if I have two members in each parent class? Can DiamondTrap inherit on of them from FragTrap and one of them from ScravTrap? How can I do this?
There's only one ClapTrap
since you use virtual
inheritance and with that, only one _hitpoints
.
You can't have that one _hitpoints
variable carry multiple values.
First, ClapTrap
is constructed, assigning 0
, then ScravTrap
is constructed, assigning 1
and last, FragTrap
is constructed, assigning 2
- all to the same _hitpoints
variable.
I want to call the constructor of
ClapTrap
only once when creating an instance ofDiamondTrap
.
That is what you do right now.
How can I do this and also have access to both
ScravTrap::_hitpoints
andFragTrap::_hitpoints
?
You can't. You'll have to select one or the other.
Without virtual
inheritance, you'll have two constructor calls and ScravTrap::_hitpoints
and FragTrap::_hitpoints
.
With virtual
inheritance, you'll have one constructor call and only one _hitpoints
.