Traté de llamar ::deletepara una clase en el operator deletemismo. Pero el destructor no se llama.
Definí una clase MyClassque operator deleteha sido sobrecargada. Lo global operator deletetambién está sobrecargado. El sobrecargado operator deletede MyClassllamará al global sobrecargado operator delete.
class MyClass
{
public:
MyClass() { printf("Constructing MyClass...\n"); }
virtual ~MyClass() { printf("Destroying MyClass...\n"); }
void* operator new(size_t size)
{
printf("Newing MyClass...\n");
void* p = ::new MyClass();
printf("End of newing MyClass...\n");
return p;
}
void operator delete(void* p)
{
printf("Deleting MyClass...\n");
::delete p; // Why is the destructor not called here?
printf("End of deleting MyClass...\n");
}
};
void* operator new(size_t size)
{
printf("Global newing...\n");
return malloc(size);
}
void operator delete(void* p)
{
printf("Global deleting...\n");
free(p);
}
int main(int argc, char** argv)
{
MyClass* myClass = new MyClass();
delete myClass;
return EXIT_SUCCESS;
}
El resultado es:
Newing MyClass...
Global newing...
Constructing MyClass...
End of newing MyClass...
Constructing MyClass...
Destroying MyClass...
Deleting MyClass...
Global deleting...
End of deleting MyClass...
Real:
Solo hay una llamada al destructor antes de llamar al sobrecargado operator deletede MyClass.
Esperado:
Hay dos llamadas al destructor. Uno antes de llamar al sobrecargado operator deletede MyClass. Otro antes de llamar a lo global operator delete.
::delete p;provoca un comportamiento indefinido ya que el tipo de *pno es el mismo que el tipo del objeto que se está eliminando (ni una clase base con destructor virtual)
void*operando está explícitamente mal formado. [expr.delete] / 1 : " El operando será de puntero a tipo de objeto o de tipo de clase. [...] Esto implica que un objeto no puede eliminarse usando un puntero de tipo void porque void no es un tipo de objeto. * "@OP He modificado mi respuesta.
MyClass::operator new()debe asignar memoria en bruto, de (al menos)sizebytes. No debe intentar construir completamente una instancia deMyClass. El constructor deMyClassse ejecuta despuésMyClass::operator new(). Luego, ladeleteexpresión inmain()llama al destructor y libera la memoria (sin volver a llamar al destructor). La::delete pexpresión no tiene información sobre el tipo deppuntos de objeto , ya quepes avoid *, por lo que no puede invocar al destructor.