İçinde ::delete
bir sınıf çağırmaya çalıştım operator delete
. Ancak yıkıcı çağrılmaz.
Dersim tanımlanmış MyClass
olan operator delete
aşırı. Küresel operator delete
de aşırı yüklü. Aşırı operator delete
ait MyClass
Aşırı yüklenmiş küresel arayacak 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;
}
Çıktı:
Newing MyClass...
Global newing...
Constructing MyClass...
End of newing MyClass...
Constructing MyClass...
Destroying MyClass...
Deleting MyClass...
Global deleting...
End of deleting MyClass...
Gerçek:
Aşırı çağırmadan önce yıkıcı ilgili yalnızca bir çağrı vardır operator delete
ve MyClass
.
Beklenen:
Yıkıcıya iki çağrı var. Aşırı çağırmadan önce biri operator delete
arasında MyClass
. Başka bir küresel çağırmadan önce operator delete
.
::delete p;
, türü *p
silinmekte olan nesnenin türüyle (veya sanal yıkıcılı bir temel sınıfla) aynı olmadığından tanımlanmamış davranışa neden oluyor
void*
işlenen bile açıkça kötü biçimlendirilmiş olduğunu fark etmedim . [expr.delete] / 1 : " İşlenen , nesne türüne veya sınıf türüne işaretçi olacaktır. [...] Bu, void türünde bir işaretçi kullanılarak bir nesnenin void türünde bir işaretçi kullanılarak silinemeyeceği anlamına gelir . * "@OP Cevabımı değiştirdim.
MyClass::operator new()
(en az)size
baytlık ham bellek ayırmalıdır . Bir örneğini tamamen oluşturmaya çalışmamalıdırMyClass
. YapıcısıMyClass
sonra yürütülürMyClass::operator new()
. Daha sonra, içindekidelete
ifade yıkıcıyımain()
çağırır ve hafızayı serbest bırakır (yıkıcıyı tekrar çağırmadan).::delete p
İfade nesne türü hakkında bir bilgi alırp
, çünkü en noktap
a,void *
böylece yıkıcı refarans olarak,.