pimpl:用pimpl避免指向指针

时间:2011-04-07 08:57:43

标签: c++ c++11 shared-ptr pimpl-idiom unique-ptr

在这个问题中,我问"pimpl: shared_ptr or unique_ptr"我一直认为正确使用pimpl习语是使用unique_ptr,而不是shared_ptr。它应该对用户起作用,好像根本没有指针,而很明显shared_ptr在复制时引入了别名,这肯定就像一个指针。

所以,假设一个用户想要为我的pimpl对象创建一个shared_ptr(比如他们真的想要多个别名)。例如:

shared_ptr<my_pimpl> p(new my_pimpl());

这会导致shared_ptr指向指向我的实现的unique_ptr

如果能够达到以下目标,那就太好了:

my_pimpl x; // (1)
shared_ptr<my_pimpl> p(new my_pimpl()); // (2) Pointer to pointer here.
x.f(); // (3)
p->f(); // (4)

但以某种方式摆脱指向指针的指针,同时仍然保持pimpl的实现隐藏。

任何想法如何实现这一点(我很乐意改变第(2)行,显然是my_pimpl,但希望第(3)和(4)行保持不变)。

2 个答案:

答案 0 :(得分:2)

根据您的限制,有许多可能的方法。

1。创建自己的shared_my_pimpl类

创建一个类shared_my_pimpl,它与my_pimpl具有相同的接口,但内部使用shared_ptr而不是unique_ptr。现在创建一个类shared_ptr_my_pimpl,其中包含shared_my_pimpl并且operator->返回指向shared_my_pimpl的指针,以便您获得->符号而不是. {1}}成员访问的表示法。您可以添加函数make_shared_ptr_my_pimpl,使其看起来更像shared_ptr用法。

缺点:

  1. 对象的类型不是shared_ptr<x>,而是shared_ptr_my_pimpl;它只是伪装成shared_ptr
  2. 您无法获得对象的my_pimpl*my_pimpl&;它是一种行为相同的不同类型。
  3. 2。从界面派生

    创建一个界面my_pimpl_interface,其中所有相关功能都是纯虚拟的。从此接口派生my_pimplmy_pimpl::impl(您的pimpl实现类)。添加一个函数make_shared_my_pimpl,将shared_ptr<my_pimpl_interface>返回给my_pimpl::impl。您现在可以将普通对象和shared_ptr对象都称为my_pimpl_interface&

    缺点:

    1. 通过虚拟化所有功能,您可以在调用它们时产生额外的间接性,这可能是您试图避免的。您的标准my_pimpl对象也将支付此开销。

答案 1 :(得分:0)

您应该使用界面来实现此目的,因为您的班级用户可以选择是否要使用shared_ptrunique_ptr