如何为pimpl使用unique_ptr? [英] How do I use unique_ptr for pimpl?

查看:233
本文介绍了如何为pimpl使用unique_ptr?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是一个简单的我看到当我尝试使用unique_ptr pimpl。我选择了unique_ptr,因为我真的想让类拥有指针 - 我想要的pimpl指针和类的生命周期是一样的。

Here is a simplification of what I'm seeing when I try to use unique_ptr for pimpl. I chose unique_ptr because I really want the class to own the pointer - I want the lifetimes of the pimpl pointer and the class to be the same.

无论如何,这里是

#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}}
{ }

我可以将这些编译成库。但是当我尝试在测试程序中使用它时,我得到

I could compile these into a library just fine. But when I try to use it in a test program I get

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'

这是一个众所周知的安全功能。我试着跟着。

This is a well known safety feature. I've tried to follow.

我的问题是,如果我把一个标题中的帮助:: Impl声明,似乎避免了pimpl的任何优势。类布局对用户可见。定义是隐藏的,但我可以这样做与帮助类和私人成员。此外,包括Impl的声明带来了我希望保持分离的新标题。

My problem is that if I put Help::Impl declaration in a header it would seem to obviate any advantage of pimpl. The class layout is visible to users. The definition is hidden but I could have done that with the Help class and private members. Also, including the declaration of Impl brings in new headers that I would have liked to keep separate.

我缺少什么?人们在Impl声明中放在什么地方?我在做帮助错误吗?我相信你的test_help.cpp实际上看到〜Help()

What am I missing? What do folks put in an Impl declaration and where? Am I doing the Help dtor wrong? Argh!

推荐答案

c $ c>析构函数。在析构函数中,编译器尝试生成 unique_ptr 析构函数,但它需要 Impl 声明。

I believe that your test_help.cpp actually sees the ~Help() destructor that you declared default. In that destructor, the compiler tries to generate the unique_ptr destructor, too, but it needs the Impl declaration for that.

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

So if you move the destructor definition to the Help.cpp, this problem should be gone.

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

-- EDIT -- You can define the destructor to be default in the cpp file, too:

Help::~Help() = default;

这篇关于如何为pimpl使用unique_ptr?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆