Pregunta

A continuación se muestra un problema de diamante en la herencia múltiple,

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 ! "); 
}

La salida que obtengo es

  1. Constructor base vacío
  2. Derivado2 un constructor arg
  3. Derivado1 un constructor arg
  4. Constructor derivado
  5. Destructor derivado vacío
  6. Destructor Derived2 vacío
  7. Vacío Derivado1 Destructor
  8. Destructor de base vacío

Me pregunto por qué mi parámetro deroBJ, es decir, "Imprimir esto si puedes" no se imprime y la salida no es como

  1. Constructor base vacío
  2. Derivado2 un constructor arg
  3. Imprima esto si puedes!
  4. Derivado1 un constructor arg
  5. Constructor derivado
  6. Destructor derivado vacío
  7. Destructor Derived2 vacío
  8. Vacío Derivado1 Destructor
  9. Destructor de base vacío
¿Fue útil?

Solución

Esto tiene que ver con la herencia virtual.

Cuando una clase se hereda virtualmente, es la responsabilidad del clase más derivada en la jerarquía para llamar a su constructor: aquí Derived.

Ya que Base es predeterminado construcible y no precisó nada, Derived invoca el constructor predeterminado de Base.

Si desea que se imprima la cadena, use:

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

Puede eliminar el constructor predeterminado para que el compilador diagnostice el problema, aunque no todos los compiladores dan mensajes muy útiles.

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