如何将unique_ptr用于pimpl
How do I use unique_ptr for pimpl?
以下是我尝试将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
以下是来源:
#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}}
{ }
我可以把这些汇编成一个图书馆。但当我尝试在测试程序中使用它时,我会得到
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'
这是一个众所周知的安全功能。我试着跟随。
我的问题是,如果我把Help::Impl声明放在一个头中,它似乎可以消除pimpl的任何优势。类布局对用户可见。定义是隐藏的,但我本可以用Help类和私有成员来完成。此外,包含Impl的声明会带来新的头,我本想将它们分开。
我错过了什么?人们在Impl声明中放了什么?放在哪里?我是不是做错了求助电话?啊!
我相信您的test_help.cpp实际上看到了您声明为默认的~Help()
析构函数。在该析构函数中,编译器也尝试生成unique_ptr
析构函数,但它需要Impl
声明。
因此,如果您将析构函数定义移动到Help.cpp,那么这个问题就应该消失了。
--编辑--您也可以在cpp文件中将析构函数定义为默认值:
Help::~Help() = default;
请注意unique_ptr定义中的这一点:
std::unique_ptr可以为不完整的类型T构造,例如便于在pImpl习惯用法中用作句柄。如果使用默认的deleter,则T必须在代码中调用deleter的位置完成,这发生在std::unique_ptr的析构函数、移动赋值运算符和重置成员函数中。
相关文章:
- 1d 智能指针不适用于语法 (*)++
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 用于访问容器<T>数据成员的正确 API
- 重载操作程序时出错>>用于类中的字符串 memebr
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- C++中的cin.ignore()函数不适用于整个流
- 没有用于初始化C++中的变量模板的匹配构造函数
- 用于C++中带有数组和指针的循环
- 为什么它不适用于Visual 2019的原因
- 使用在用于SFINAE的void_t中具有参数的方法
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 重载==不适用于二进制树
- Insert函数不适用于2 if语句C++
- 用于矢量处理的多个线程
- 使外部项目可用于find_package CMake
- 在子目录中使用target_sources()命令时用于单元测试(qtest)的项目结构
- 为什么模数运算符不适用于该代码
- 唯一/共享 ptr 用于在数组超出范围后自动删除阵列
- 取消引用适用于 ptr->运算符*(),但不适用于 *ptr
- shared-ptr-C++shared_ptr与unique_ptr用于资源管理