나는 그것 ::delete
의 수업 을 요청 operator delete
했습니다. 그러나 소멸자는 호출되지 않습니다.
과부하 된 클래스 MyClass
를 정의했습니다 operator delete
. 글로벌 operator delete
도 과부하 상태입니다. 오버로드 operator delete
의이 MyClass
v로드 세계를 호출합니다 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;
}
출력은 다음과 같습니다.
Newing MyClass...
Global newing...
Constructing MyClass...
End of newing MyClass...
Constructing MyClass...
Destroying MyClass...
Deleting MyClass...
Global deleting...
End of deleting MyClass...
실제 :
의 오버로드 operator delete
를 호출하기 전에 소멸자에 대한 호출이 하나만 있습니다 MyClass
.
예상 :
소멸자를 두 번 호출합니다. 오버로드 된 호출하기 전에 하나 operator delete
의 MyClass
. 다른 하나는 글로벌 전화하기 전에 operator delete
.
::delete p;
유형 *p
이 삭제되는 객체의 유형과 같지 않기 때문에 정의되지 않은 동작이 발생 합니다 (가상 소멸자가있는 기본 클래스도 아님)
void*
피연산자가 명시 적으로 잘못 구성되어 있음을 알지 못했습니다 . [expr.delete] / 1 : " 피연산자는 객체 유형 또는 클래스 유형에 대한 포인터 여야합니다. [...] 이는 void가 객체 유형이 아니기 때문에 void 유형의 포인터를 사용하여 객체를 삭제할 수 없음을 의미합니다 . * "@OP 답변을 수정했습니다.
MyClass::operator new()
(최소한)size
바이트 의 원시 메모리를 할당해야 합니다. 의 인스턴스를 완전히 구성하려고 시도해서는 안됩니다MyClass
. 의 생성자는 다음MyClass
에 실행MyClass::operator new()
됩니다. 그런 다음delete
in 식은main()
소멸자를 호출하고 소멸자를 다시 호출하지 않고 메모리를 해제합니다.::delete p
표현은 객체의 유형에 대한 정보가 없습니다p
이후에 포인트를p
A는void *
그래서 소멸자를 호출 할 수 없습니다.