2011-10-25 3 views
1

boost::scoped_ptr documentation에는 Handle/Body Idiom이라고하는 기술의 예가 들어 있습니다. 그것은 다음 단어에 대하여 설명된다 :boost :: scoped_ptr 문서 불일치?

scoped_ptr_example_test.cpp 샘플 프로그램 실행을 숨길 불완전 형 에 scoped_ptr를 <>를 사용하는 헤더 파일 scoped_ptr_example.hpp를 포함한다.

은 그러나, 동시에, documentation for checked_delete에서이 적혀있다 :

특히 까다로운 경우가 때 스마트 포인터의 소멸자, 같은 부스트 :: scoped_ptr를 :: ~ scoped_ptr를, 불완전한 유형으로 인스턴스화됩니다. 이로 인해 종종 침묵하고 추적하기 어려운 오류가 발생할 수 있습니다. 은 완전한 유형이 필요하고 그렇지 않으면 컴파일 오류가 발생하므로 제공된 함수 및 클래스 템플릿을 사용하여 이러한 문제를 방지 할 수 있습니다.

scoped_ptr 실제로 구현시 checked_delete을 사용합니다. 내게는 두 구절이 서로 모순 된 것처럼 보입니다. scoped_ptr의 문서는 erronous, 실제로 그렇습니다

checked_delete.hpp:32: error: invalid application of 'sizeof' to 
incomplete type 'MyClass' 

또는 그냥 뭔가를 그리워 : 또한, 나는 다음과 같은 메시지가 제안 트릭을 사용하려고 내 코드를 컴파일하지?

답변

4

그들은 서로 모순되지 않습니다. scoped_ptr은 템플릿이기 때문에 코드에 명시적인 인스턴스화가 없기 때문에 필요에 따라 각 메서드가 인스턴스화됩니다. 즉, ~scoped_ptr<>이 인스턴스화 된 시점까지 유형이 완료되어야하며,이 경우 보류 된 유형이 완료된 후 .cpp 파일에 있습니다 (example::~example(){}이 파일의 끝에 가까워지며 여기에서 ~scoped_ptr<>이 인스턴스화됩니다).)

이 실제로 정확히 것 생성 된 컴파일러와 같은 모양 사용자 정의 소멸자에 대한 흥미로운 사용 사례이지만 을 제어 할 수 있습니다 곳/ 파괴 일부와 PIMPL 패턴을 사용하려면 어떻게 스마트 포인터. 소멸자가 선언되고 정의되지 않은 경우 필요에 따라 소멸자가 컴파일러에 의해 암시 적으로 정의되며 유형이 불완전하여 UB가 발생합니다.

+0

실제로 소멸자와 생성자는 모두 사용자 정의되어야합니다. 컴파일러가 생성 된 생성자가 기본 생성자를 사용하면 컴파일러는 유형이 불완전한'main()'에서'scoped_ptr'을 인스턴스화하려고 시도합니다. – FireAphis

+0

실제로 'shared_ptr'과 같은 문제는 유형 삭제를 사용하여 생성자에 인스턴스화 된 삭제 객체를 만들기 때문에 발생하지 않습니다. 참고로 클래스의 불완전 유형에'shared_ptr'을 사용하고이 클래스의 생성자 만 정의 할 수 있습니다. –

+0

@FireAphis : 생성자를 사용자 정의 할 필요는 없습니다. 'scope_ptr' 템플릿의 인스턴스화는'scope_ptr'의 소멸자가 인스턴스화된다는 의미는 아니며 사용 된 메소드 만 인스턴스화됩니다. 그리고 불완전한 타입의 생성자를 사용하는 것이 정의되지 않았다고 생각하지 않습니다 불완전한 타입의 경우에는 괜찮은 포인터를 전달/저장) - 즉, 생성자가 타입을 동적으로 할당하지 않았다고 가정합니다. 여기서 불완전한 타입이 다시 문제가되는 경우입니다. –

2

클래스 템플릿의 멤버 함수는 이 사용 된 경우에만 인스턴스화됩니다. 유일한 곳은 boost::scoped_ptr::~scoped_ptr이며, example의 소멸자 에 사용됩니다. scoped_ptr_example.cpp에 정의 된 후 example::implementation의 정의가 정의됩니다. 함수 boost::checked_delete은 유형이 불완전한 경우 컴파일되지 않도록 설계되었습니다. boost::scoped_ptr::~scoped_ptr은 이것을 사용하므로 유형이 완료되지 않은 컨텍스트에서 코드를 호출하려고하면 코드가 컴파일되지 않습니다.

(FWIW 다음 pimpl 관용구에 boost::scoped_ptr를 사용하여 비트 과잉, 아니라 매우 유용입니다, 당신은 어쨌든 사용자 정의 소멸자 을 제공해야하기 때문에, 정말 많이 구입하지 않고, 추가 작은 비트 복잡도)

+0

pimpl 관용구에서 "_using'boost :: scoped_ptr'는 조금 지나치게 비싸고 유용하지는 않습니다."독점적 인 소유권을 표현하는 데 scoped_ptr을 사용하는 것은 분명하고, 자체 문서화되고, 좋은 습관입니다. – curiousguy

+0

@curiousguy'scoped_ptr'는 여러분이 여전히 소멸자를 구현해야하기 때문에 pimpl 관용구에서 많은 것을 사지 않습니다. 인 텐트의 문서화에 대한 논쟁을 이해할 수는 있지만, 클래스에 myImpl이라는 이름의 포인터 하나가 포함되어 있고 Impl이라는 타입이 있다면 그 의도는 분명하다. 당신은 배타적 인 소유권을 표현하는 것을 넘어 섰고 사용 된 실제 패턴을 분명히했습니다. –

+0

대부분의 의견에 동의합니다. 하지만 독점적 인 소유권이 관련되는 경우 가능한 경우 scoped_ptr을 사용하십시오. (하지만 네가 그렇게하지 않으면 나는 괜찮을 것이다.) – curiousguy