여기는 pimpl에 대해 unique_ptr을 사용하려고 시도하는 것을 단순화 한 것입니다. 나는 클래스가 정말로 포인터를 소유하기를 원하기 때문에 unique_ptr을 선택했다 - 나는 pimpl 포인터와 클래스의 수명을 같게하고 싶다. 여기pimpl에 unique_ptr을 어떻게 사용합니까?
#ifndef HELP
#define HELP 1
#include <memory>
class Help
{
public:
Help(int ii);
~Help() = default;
private:
class Impl;
std::unique_ptr<Impl> _M_impl;
};
#endif // HELP
소스입니다 :
#include "Help.h"
class Help::Impl
{
public:
Impl(int ii)
: _M_i{ii}
{ }
private:
int _M_i;
};
Help::Help(int ii)
: _M_impl{new Help::Impl{ii}}
{ }
내가 잘 라이브러리로이 컴파일 할 수
어쨌든, 여기 헤더입니다. 제가 테스트 프로그램에서 사용하려고 할 때하지만 이것은 잘 알려진 safety feature입니다
[email protected]:~/ext_distribution$ ../bin/bin/g++ -std=c++0x -o test_help test_help.cpp Help.cpp
In file included from /home/ed/bin/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/memory:86:0,
from Help.h:4,
from test_help.cpp:3:
/home/ed/bin/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h: In instantiation of 'void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = Help::Impl]':
/home/ed/bin/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:245:4: required from 'void std::unique_ptr<_Tp, _Dp>::reset(std::unique_ptr<_Tp, _Dp>::pointer) [with _Tp = Help::Impl; _Dp = std::default_delete<Help::Impl>; std::unique_ptr<_Tp, _Dp>::pointer = Help::Impl*]'
/home/ed/bin/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:169:32: required from 'std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = Help::Impl; _Dp = std::default_delete<Help::Impl>]'
Help.h:6:7: required from here
/home/ed/bin/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:63:14: error: invalid application of 'sizeof' to incomplete type 'Help::Impl'
얻을. 나는 따라하려고 노력했다.
제 문제는 헤더에 Help :: Impl 선언을 넣으면 pimpl의 이점을 없애는 것 같습니다. 클래스 레이아웃은 사용자에게 표시됩니다. 정의는 숨겨져 있지만 도움말 클래스와 비공개 멤버로 할 수 있습니다. 또한 Impl의 선언을 포함하여 내가 별도로 유지하기를 좋아할만한 새로운 헤더를 가져온다.
무엇이 누락 되었습니까? 여러분은 Impl 선언에 무엇을 넣었습니까? 내가 잘못된 dtor을하고 있습니까? 아!
[GotW # 101 : 컴파일 방화벽, 파트 2] (http://herbsutter.com/gotw/_101/) 및 [이 관련 질문] (http://stackoverflow.com/q/8595471)/636019). – ildjarn
낡은 질문이지만, 'unique_ptr'로 구현 된 PImpl은 (cppreference (http://en.cppreference.com/w/cpp/language/pimpl)에서 설명했듯이) 완전한 정확성을 위해 ['propagate_const'] (http://en.cppreference.com/w/cpp/experimental/propagate_const)와 같은 것으로 싸여 져야합니다. – jdehesa
@jdehesa 고맙습니다. 일부 API 어색함에 대한 해결책으로 propagate_const를 찾고있었습니다. unique_ptr이 기본적으로이 의미에서 손상되었는지 거의 궁금합니다. 그것은 propagate_const가 내장되어 있거나 적어도 디폴트가되어야하는 것 같습니다. – emsr