Saya mencoba menelepon ::deleteuntuk kelas di operator deletedalamnya. Tetapi destruktor tidak disebut.
Saya mendefinisikan kelas MyClassyang operator deletekelebihan beban. Global operator deletejuga kelebihan beban. The kelebihan beban operator deletedari MyClassakan memanggil global kelebihan beban 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;
}
Outputnya adalah:
Newing MyClass...
Global newing...
Constructing MyClass...
End of newing MyClass...
Constructing MyClass...
Destroying MyClass...
Deleting MyClass...
Global deleting...
End of deleting MyClass...
Sebenarnya:
Hanya ada satu panggilan untuk destructor sebelum memanggil kelebihan beban operator deletedari MyClass.
Diharapkan:
Ada dua panggilan ke destructor. Salah satu sebelum memanggil kelebihan beban operator deletedari MyClass. Lain sebelum memanggil global operator delete.
::delete p;menyebabkan perilaku tidak terdefinisi karena jenis *ptidak sama dengan jenis objek yang dihapus (atau kelas dasar dengan penghancur virtual)
void*operan bahkan secara eksplisit salah bentuk. [expr.delete] / 1 : " Operand harus dari penunjuk ke tipe objek atau tipe kelas. [...] Ini menyiratkan bahwa suatu objek tidak dapat dihapus menggunakan penunjuk tipe batal karena batal bukan tipe objek. * "@OP Saya telah mengubah jawaban saya.
MyClass::operator new()harus mengalokasikan memori mentah, dari (setidaknya)sizebyte. Seharusnya tidak berusaha untuk sepenuhnya membangun contohMyClass. KonstruktorMyClassdieksekusi setelahMyClass::operator new(). Kemudian,deleteekspresi dimain()memanggil destruktor, dan melepaskan memori (tanpa memanggil destruktor lagi). The::delete pekspresi tidak memiliki informasi tentang jenis objekppoin di, karenapmerupakanvoid *, sehingga tidak bisa memanggil destructor.