I have a problem with a Diamond inheritance exercise.
I have one base class A. Here is its constructor :
A::A(std::string name) : _hp(10), _ep(10), _ad(0)
{
std::cout << "A object created !" << std::endl;
return ;
}
Then, I have two parent classes B and C. Here are their constructors:
B::B(std::string name) : A(name)
{
std::cout << "B object created !" << std::endl;
this->_hp = 100;
this->_ep = 50;
this->_ad = 20;
return;
}
C::C(std::string name) : A(name)
{
std::cout << "C object created !" << std::endl;
this->_hp = 100;
this->_ep = 100;
this->_ad = 30;
return ;
}
And finally, I have one child class . Here is its constructor:
D::D(std::string name) : A(name "_comes_from_A")
{
this->_name = name;
std::cout << "D object created !" << std::endl;
this->_hp = C::_hp;
this->_ep = B::_ep;
this->_ad = C::_ad;
return;
}
The D class inherits from class B and C. The B and C classes both inherits from class A. I did something like this :
class A
{
// code here
protected:
std::string _name;
int _hp;
int _ep;
int _ad;
};
class B : virtual public A
{
// code here
};
class C : virtual public A
{
// code here
};
class D : public B, public C
{
// code here
};
As it can be noticed in the constructor of D class, I want it to inherits _ep from the B class (50) and _hp and _ad from the C class (100 and 30).
However, if I check the value of the _ep value in my D class, (with something like this for instance) :
std::cout << "ENERGY POINTS " << this->_ep << std::endl;
it is always equal to 100 (which comes from the C class).
I have noticed it depends on the order in which I handle inheritance for D class but I would like to be able to access values of any of the parent class from my child class. Can someone help me with that ? Thanks in advance!
MINIMAL REPRODUCIBLE EXAMPLE :
class A
{
public :
A(){
return ;
};
A(std::string name) : _hp(10), _ep(10), _ad(0){
std::cout << "A object created !" << std::endl;
return ;
};
~A(){
std::cout << "A object " << this->_name << " destroyed." << std::endl;
return ;
};
protected:
std::string _name;
int _hp;
int _ep;
int _ad;
};
class B : virtual public A
{
public :
B(){
return ;
};
B(std::string name) : A(name){
std::cout << "B object created !" << std::endl;
this->_hp = 100;
this->_ep = 50;
this->_ad = 20;
return ;
};
~B(){
std::cout << "B object " << this->_name << " destroyed." << std::endl;
return ;
};
};
class C : virtual public A
{
public :
C(){
return ;
};
C(std::string name) : A(name){
std::cout << "C object created !" << std::endl;
this->_hp = 100;
this->_ep = 100;
this->_ad = 30;
return ;
};
~C(){
std::cout << "C object " << this->_name << " destroyed." << std::endl;
return ;
};
};
class D : public B, public C
{
public :
D(){
return ;
};
D(std::string name) : A(name "_comes_from_a"){
this->_name = name;
std::cout << "D object created !" << std::endl;
this->_hp = C::_hp;
this->_ep = B::_ep;
this->_ad = C::_ad;
std::cout << "HIT POINTS " << this->_hp << std::endl;
std::cout << "ENERGY POINTS " << this->_ep << std::endl;
std::cout << "ATTACK DAMAGE " << this->_ad << std::endl;
return;
}
~D(){
std::cout << "D object " << this->_name << " destroyed." << std::endl;
return ;
};
};
int main(void)
{
D obj_D("TEST");
return (0);
}
CodePudding user response:
Okay, I got my program to work properly. Maybe I didn't explain well what I wanted to do, but I'm posting my solution here.
There are 4 classes A, B, C and D. They all have _hp, _ep and _ad variables.
D inherits from B AND C, which in turn inherit from A.
A
/ \
B C
\ /
D
I wanted my D class to take :
- _ep value from the B class
- _hp and _ad values from the C class
Here is the minimal reproducible example of the code that worked for me :
# include <iostream>
# include <string>
class A
{
public :
A(){
return ;
};
A(std::string name) : _hp(10), _ep(10), _ad(0){
std::cout << "A object created !" << std::endl;
return ;
};
~A(){
std::cout << "A object " << this->_name << " destroyed." << std::endl;
return ;
};
protected:
std::string _name;
int _hp;
int _ep;
int _ad;
};
class B : virtual public A
{
public :
B(){
return ;
};
B(std::string name) : A(name){
std::cout << "B object created !" << std::endl;
this->_hp = 100;
this->_ep = 50;
this->_ad = 20;
return ;
};
~B(){
std::cout << "B object " << this->_name << " destroyed." << std::endl;
return ;
};
static const int EP = 50;
};
class C : virtual public A
{
public :
C(){
return ;
};
C(std::string name) : A(name){
std::cout << "C object created !" << std::endl;
this->_hp = 100;
this->_ep = 100;
this->_ad = 30;
return ;
};
~C(){
std::cout << "C object " << this->_name << " destroyed." << std::endl;
return ;
};
static const int HP = 100;
static const int AD = 30;
};
class D : public B, public C
{
public :
D(){
return ;
};
D(std::string name) : A(name "_comes_from_a"){
this->_name = name;
std::cout << "D object created !" << std::endl;
this->_hp = C::HP;
this->_ep = B::EP;
this->_ad = C::AD;
std::cout << "HIT POINTS " << this->_hp << std::endl;
std::cout << "ENERGY POINTS " << this->_ep << std::endl;
std::cout << "ATTACK DAMAGE " << this->_ad << std::endl;
return;
}
~D(){
std::cout << "D object " << this->_name << " destroyed." << std::endl;
return ;
};
};
int main(void)
{
D obj_D("TEST");
return (0);
}
The difference with the example that I posted in the question is that I declared static const int
variables (HP, EP and AD) in my B and C classes. Thus, I am now able to access the values either from B or C classes in the constructor of class D. Typically, what I did earlier was wrong :
// before (not working)
this->_hp = C::_hp;
this->_ep = B::_ep;
this->_ad = C::_ad;
// now (working)
this->_hp = C::HP;
this->_ep = B::EP;
this->_ad = C::AD;
The output is now :
A object created !
D object created !
HIT POINTS 100
ENERGY POINTS 50
ATTACK DAMAGE 30
D object TEST destroyed.
C object TEST destroyed.
B object TEST destroyed.
A object TEST destroyed.