【问题标题】:pimpl: Avoiding pointer to pointer with pimplpimpl:避免使用 pimpl 指向指针的指针
【发布时间】:2011-04-07 08:57:42
【问题描述】:

在这个问题中,我问过"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) 行保持不变)。

【问题讨论】:

  • 'my_pimpl' 是公共类还是私有类?
  • 其实没关系。如果第 3 行有效,则第 4 行也有效,假设“shared_ptr”具有预期的语义。即使 'my_pimpl' 是 'unique_ptr' 的 typedef,'operator->' 也会很好地“深入”到底层类型。

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


【解决方案1】:

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

1。创建您自己的 shared_my_pimpl 类

创建一个类shared_my_pimpl,它与my_pimpl 具有相同的接口,但在内部使用shared_ptr 而不是unique_ptr。现在创建一个类shared_ptr_my_pimpl,它包含一个shared_my_pimpl 和一个operator-&gt;,它返回一个指向shared_my_pimpl 的指针,这样您就可以得到-&gt; 符号而不是. 符号来访问成员。你可以添加一个函数make_shared_ptr_my_pimpl,让它看起来更像shared_ptr的用法。

缺点:

  1. 对象的类型不是shared_ptr&lt;x&gt;而是shared_ptr_my_pimpl;它只是假装是shared_ptr
  2. 您无法为对象获取my_pimpl*my_pimpl&amp;;它是一种不同的类型,只是行为相同。

2。从接口派生

创建一个接口my_pimpl_interface,所有相关功能都是纯虚拟的。从这个接口派生my_pimplmy_pimpl::impl(你的pimpl 实现类)。添加一个函数make_shared_my_pimpl,它将shared_ptr&lt;my_pimpl_interface&gt; 返回到my_pimpl::impl。您现在可以将普通对象和 shared_ptr 对象都称为my_pimpl_interface&amp;

缺点:

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

【讨论】:

    【解决方案2】:

    您应该为此目的使用一个接口,因为您的类的用户可以选择是否要使用shared_ptrunique_ptr

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-26
      • 1970-01-01
      • 1970-01-01
      • 2012-01-13
      • 2016-10-13
      • 2017-02-18
      • 1970-01-01
      相关资源
      最近更新 更多