문제

다음 코드에서 개인 소멸 자로 객체를 삭제할 수있는 방법은 무엇입니까? 실제 프로그램을 다음 샘플로 줄였지만 여전히 컴파일하고 작동합니다.

class SomeClass;

int main(int argc, char *argv[])
{
  SomeClass* boo = 0; // in real program it will be valid pointer
  delete boo; // how it can work?

  return -1;
}

class SomeClass
{
private:
  ~SomeClass() {}; // ! private destructor !
};
도움이 되었습니까?

해결책

불완전한 클래스 유형의 객체를 삭제하려고합니다. C ++ 표준은이 경우 (5.3.5/5)에서 정의되지 않은 동작을 얻을 수 있다고 말합니다.

삭제되는 객체의 삭제 시점에서 불완전한 클래스 유형이없고 전체 클래스에 사소한 파괴자 또는 거래 기능이있는 경우 동작이 정의되지 않습니다.

이러한 경우를 감지하려면 사용할 수 있습니다 boost::checked_delete:

template<typename T> 
inline void checked_delete( T* p )
{
    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
    (void) sizeof(type_must_be_complete);
    delete p;
}

다른 팁

이 코드는 정의되지 않은 동작 (UB)을 유발합니다. C ++로 UB입니다 delete 사소한 파괴자가있는 불완전한 유형의 대상. 그리고 코드에서 유형 SomeClass 지점에서 불완전합니다 delete, 그리고 그것은 사소한 파괴자가 있습니다. 컴파일러는 일반적으로 C ++에서 공식적으로 제약 위반이 아니기 때문에 일반적으로 이에 대한 경고를 발행합니다.

따라서 엄밀히 말하면 코드는 "작동하지 않습니다". 간단합니다 컴파일 그리고 뭔가를합니다 한정되지 않은 실행할 때.

컴파일러는이 오류를 포착 할 필요가 없습니다. 그 이유는 당신의 물체가 하찮은 폐물 소각로. 컴파일러는이 유형이 결국 어떤 종류의 파괴자를 가질 지 알 수있는 방법이 없으므로 이것이 오류인지 아닌지는 확실하게 말할 수 없습니다.

왜냐하면 SomeClass 호출 할 때 유형이 완전히 선언되지 않습니다 operator delete.

이러한 포인터를 삭제하는 것은 정의되지 않은 동작이지만 실제로 대부분의 컴파일러는 메모리를 제거하고 (포인터가 널이 아닌 경우) 소멸자를 호출하지 않습니다.

예를 들어, G ++는이 문제에 대한 경고를 제공합니다.

foo.cpp: In function 'int main(int, char**)':
foo.cpp:6: warning: possible problem detected in invocation of delete operator:
foo.cpp:5: warning: 'boo' has incomplete type
foo.cpp:1: warning: forward declaration of 'struct SomeClass'
foo.cpp:6: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top