Saya mencoba menelepon ::delete
untuk kelas di operator delete
dalamnya. Tetapi destruktor tidak disebut.
Saya mendefinisikan kelas MyClass
yang operator delete
kelebihan beban. Global operator delete
juga kelebihan beban. The kelebihan beban operator delete
dari MyClass
akan 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 delete
dari MyClass
.
Diharapkan:
Ada dua panggilan ke destructor. Salah satu sebelum memanggil kelebihan beban operator delete
dari MyClass
. Lain sebelum memanggil global operator delete
.
::delete p;
menyebabkan perilaku tidak terdefinisi karena jenis *p
tidak 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)size
byte. Seharusnya tidak berusaha untuk sepenuhnya membangun contohMyClass
. KonstruktorMyClass
dieksekusi setelahMyClass::operator new()
. Kemudian,delete
ekspresi dimain()
memanggil destruktor, dan melepaskan memori (tanpa memanggil destruktor lagi). The::delete p
ekspresi tidak memiliki informasi tentang jenis objekp
poin di, karenap
merupakanvoid *
, sehingga tidak bisa memanggil destructor.