ems*_*msr 60 c++ pimpl-idiom unique-ptr c++11
这是我在尝试将unique_ptr用于pimpl时所看到的简化.我选择了unique_ptr,因为我真的希望类拥有指针 - 我希望pimpl指针和类的生命周期相同.
无论如何,这是标题:
#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
Run Code Online (Sandbox Code Playgroud)
这是来源:
#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}}
{ }
Run Code Online (Sandbox Code Playgroud)
我可以将它们编译成一个库就好了.但是当我尝试在测试程序中使用它时,我得到了
ed@bad-horse:~/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'
Run Code Online (Sandbox Code Playgroud)
这是众所周知的安全功能.我试着跟着.
我的问题是,如果我在一个标题中放入Help :: Impl声明,它似乎可以消除pimpl的任何优点.用户可以看到类布局.该定义是隐藏的,但我可以使用Help类和私有成员完成此操作.此外,包括Impl的声明带来了我希望保持分离的新标题.
我错过了什么?人们在Impl宣言中放了什么?我在帮助dtor做错了吗?哎呀!
xto*_*ofl 80
我相信你的test_help.cpp实际上看到~Help()
你声明默认的析构函数.在该析构函数中,编译器也尝试生成unique_ptr
析构函数,但它需要Impl
声明.
因此,如果将析构函数定义移动到Help.cpp,则此问题应该消失.
- 编辑 - 您也可以将析构函数定义为cpp文件中的默认值:
Help::~Help() = default;
Run Code Online (Sandbox Code Playgroud)
请注意unique_ptr定义:
可以为不完整类型T构造std :: unique_ptr,例如以便于在pImpl习语中用作句柄.如果使用默认删除器,则必须在调用删除器的代码中完成T,这发生在析构函数,移动赋值运算符和std :: unique_ptr的重置成员函数中.
归档时间: |
|
查看次数: |
16667 次 |
最近记录: |