Pregunta

Below is a diamond problem faced in multiple inheritance,

class Base {
 public:
  Base() {
    cout << "Empty Base constructor " << endl; 
  }
  Base(const string & strVar) { 
    m_strVar = strVar; 
    cout << m_strVar << endl;
  }
  virtual ~Base() {
    cout << "Empty Base destructor " << endl;
  }
  virtual const string & strVar() const { 
   return m_strVar; 
  }

  string m_strVar;
};

class Derived1: public virtual Base {
 public:
  Derived1() {
    cout << "Empty Derived1 constructor " << endl; 
  }
  Derived1(const string & strVar) : Base(strVar) {
    cout << " Derived1 one arg constructor" << endl;
  }
  ~Derived1() {
    cout << "Empty Derived1 destructor " << endl;
  }
};

class Derived2: public virtual Base {
 public:
  Derived2() {
    cout << "Empty Derived2 constructor " << endl; 
  }
  Derived2(const string & strVar) : Base(strVar) {
    cout << "Derived2 one arg constructor" << endl;
  }
  ~Derived2() {
    cout << "Empty Derived2 destructor " << endl;
  }
};

class Derived: public Derived1, public Derived2 {
 public:
  Derived(const string & strVar) : Derived1(strVar), Derived2(strVar) {
    cout << "Derived Constructor " << endl; 
  }
  ~Derived() {
    cout << "Empty Derived destructor " << endl;
  }
};

int main() {
  Derived derObj ("Print this if you can ! "); 
}

the output i get is

  1. Empty Base constructor
  2. Derived2 one arg constructor
  3. Derived1 one arg constructor
  4. Derived Constructor
  5. Empty Derived destructor
  6. Empty Derived2 destructor
  7. Empty Derived1 destructor
  8. Empty Base destructor

i wonder why my derObj parameter i.e "Print this if you can" is not printed and output is not like

  1. Empty Base constructor
  2. Derived2 one arg constructor
  3. Print this if you can!
  4. Derived1 one arg constructor
  5. Derived Constructor
  6. Empty Derived destructor
  7. Empty Derived2 destructor
  8. Empty Derived1 destructor
  9. Empty Base destructor
¿Fue útil?

Solución

This has to do with virtual inheritance.

When a class is inherited virtually, it is the responsability of the most derived class in the hierarchy to call its constructor: here Derived.

Since Base is default constructible and you did not precise anything, Derived invokes the default constructor of Base.

If you want the string to be printed, use:

Derived(const string & strVar) : Base(strVar), Derived1(strVar), Derived2(strVar)
{
  std::cout << "Derived Constructor\n"; 
}

You could remove the default constructor to let the compiler diagnose the issue, though not all compilers give very helpful messages.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top