首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将unique_ptr用于pimpl?

如何将unique_ptr用于pimpl?
EN

Stack Overflow用户
提问于 2012-01-26 23:19:15
回答 1查看 19.8K关注 0票数 62

这是我在pimpl中使用unique_ptr时所看到的一个简化。我选择unique_ptr是因为我真的想让类拥有指针--我希望pimpl指针和类的生命周期是一样的。

无论如何,这是头文件:

代码语言:javascript
复制
#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

以下是源代码:

代码语言:javascript
复制
#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}}
{ }

我可以把它们编译成一个库。但是当我尝试在测试程序中使用它时,我得到

代码语言:javascript
复制
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'

这是一个众所周知的safety feature。我试着跟上了。

我的问题是,如果我将Help::Impl声明放在头文件中,它似乎会消除pimpl的任何优势。类布局对用户可见。定义是隐藏的,但我可以使用Help类和私有成员来实现。另外,包括Impl的声明带来了新的头文件,我希望将它们分开。

我遗漏了什么?人们在Impl声明中放了什么?放在哪里?我是不是做错了帮助任务?啊!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-01-26 23:24:14

我相信您的test_help.cpp实际上看到了您声明为默认的~Help()析构函数。在该析构函数中,编译器也会尝试生成unique_ptr析构函数,但需要使用Impl声明。

因此,如果您将析构函数定义移动到Help.cpp,这个问题应该会消失。

-- EDIT --您也可以将析构函数定义为cpp文件中的默认值:

代码语言:javascript
复制
Help::~Help() = default;
票数 85
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9020372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档