를 이해하려면 enum
먼저 소멸자가없는 소멸자를 고려하십시오.
~scoped_ptr() {
delete ptr_;
}
여기서 ptr_
A는 C*
. 유형의 경우 C
이 시점에서 불완전 즉,이 컴파일러가 알고있는 모든 것을 struct C;
다음, (1) 기본으로 생성 된 소멸자는 C 인스턴스에 사용 할 - 아무것도에 지적 없습니다. 스마트 포인터에 의해 관리되는 개체에 대해 옳은 일이 아닐 수 있습니다.
불완전한 유형에 대한 포인터를 통한 삭제가 항상 정의되지 않은 동작을 가지고 있었다면 표준은 컴파일러가이를 진단하고 실패하도록 요구할 수 있습니다. 그러나 실제 소멸자가 사소한 경우에는 잘 정의되어 있습니다. 프로그래머는 가질 수 있지만 컴파일러에는없는 지식입니다. 언어가 이것을 정의하고 허용하는 이유는 저를 넘어서지 만 C ++는 오늘날 모범 사례로 간주되지 않는 많은 사례를 지원합니다.
완전한 유형은 알려진 크기를 가지므로 완전한 유형 인 sizeof(C)
경우에만 C
알려진 소멸자를 사용하여 컴파일됩니다 . 따라서 가드로 사용할 수 있습니다. 한 가지 방법은 간단하게
(void) sizeof(C);
나는 것 같아 몇 가지 컴파일러 옵션 컴파일러는 그것을 컴파일되지 것을 알 수 있기 전에, 그리고 그 그것을 멀리 최적화와 함께 그 enum
같은 부적합 컴파일러 동작을 방지하는 방법입니다 :
enum { type_must_be_complete = sizeof(C) };
enum
단순히 버려지는 표현보다는 선택에 대한 대안적인 설명 은 단순히 개인적인 선호입니다.
또는 James T. Hugget 이이 답변 에 대한 주석에서 제안했듯이 "열거 형은 컴파일 타임에 의사 이식 가능한 오류 메시지를 만드는 방법 일 수 있습니다".
(1) 불완전한 유형에 대해 기본 생성 된 do-nothing 소멸자는 old std::auto_ptr
. 너무 교활 해서 국제 C ++ 표준화위원회 Herb Sutter의 위원장이 작성한 PIMPL 관용구에 대한 GOTW 항목에 포함 되었습니다. 물론 현재 std::auto_ptr
는 더 이상 사용되지 않으며 대신 다른 메커니즘을 사용합니다.
ptr_
에서 자체를 사용하는 것이 좋습니다 .sizeof
sizeof(*ptr_)
sizeof(C)