A continuación se encuentran dos fragmentos (listos para compilar) del código. En el primer fragmento en el que estoy usando solo la declaración forward para una estructura mientras elimino el puntero a esta estructura de un dtor de clase Base para una clase Guest no se invoca.
En el segundo fragmento, cuando en lugar de la declaración directa utilizo la definición completa de esta clase de Invitado utilizando delete en Base funciona como se pretendía.
¿Por qué? ¿Por qué hace la diferencia? ¿No se supone que la declaración directa es solo una nota para un compilador que dice que la definición de esta clase/estructura está en otro lugar?
Estoy muy sorprendido de que simplemente no funcione de manera intuitiva.La declaración directa no funcionará
//First just forward dclr
#include "stdafx.h"
#include <iostream>
using std::cout;
struct Guest;
struct Base
{
Guest* ptr_;
Base(Guest* ptr):ptr_(ptr)
{
cout << "Base\n";
}
~Base()
{
cout << "~Base\n";
delete ptr_;
}
};
struct Guest
{
Guest()
{
cout << "Guest\n";
throw std::exception();
}
Guest(int)
{
cout << "Guest(int)\n";
}
~Guest()
{
cout << "~Guest\n";
}
};
struct MyClass : Base
{
Guest g;
MyClass(Guest* g):Base(g)
{
cout << "MyClass\n";
}
~MyClass()
{
cout << "~MyClass\n";
}
};
int _tmain(int argc, _TCHAR* argv[])
{
try
{
Guest* g = new Guest(1);
MyClass mc(g);
}
catch(const std::exception& e)
{
std::cerr << e.what();
}
return 0;
}
// Segundo - def completa
#include "stdafx.h"
#include <iostream>
using std::cout;
struct Guest
{
Guest()
{
cout << "Guest\n";
throw std::exception();
}
Guest(int)
{
cout << "Guest(int)\n";
}
~Guest()
{
cout << "~Guest\n";
}
};
struct Base
{
Guest* ptr_;
Base(Guest* ptr):ptr_(ptr)
{
cout << "Base\n";
}
~Base()
{
cout << "~Base\n";
delete ptr_;
}
};
struct MyClass : Base
{
Guest g;
MyClass(Guest* g):Base(g)
{
cout << "MyClass\n";
}
~MyClass()
{
cout << "~MyClass\n";
}
};
int _tmain(int argc, _TCHAR* argv[])
{
try
{
Guest* g = new Guest(1);
MyClass mc(g);
}
catch(const std::exception& e)
{
std::cerr << e.what();
}
return 0;
}
Debe hacer que sus constructores de clase base sean virtuales en ambos casos. –
@ Space_C0wb0y: Estimado, no puedes hacer un constructor virtual en C++ :) –
@Armen: Palabras ... humo y espejos. Estaba tan claro en mi mente. (Para aquellos que se preguntan, debería ser * destructores *) –