pimpl:使用pimpl避免指针指针 [英] pimpl: Avoiding pointer to pointer with pimpl

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

问题描述

在此问题中,我问了pimpl:shared_ptr或unique_ptr我已经确信pimpl成语的正确使用是使用 unique_ptr ,而不是 shared_ptr 。它应该对用户起作用,就像根本没有指针一样,但是很清楚, shared_ptr 在复制时引入了别名,这肯定像一个指针。

$所以,让我们说一个用户想要创建一个 shared_ptr 到我的pimpl对象(假设他们想要实际上想要多个别名) 。例如:

  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)指向这里指针的指针。
x.f(); //(3)
p-> f(); //(4)

但是无论如何摆脱指针的指针,隐藏pimpl。



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

解决方案

可能的方法取决于你的约束。



1。创建您自己的shared_my_pimpl类



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



缺点:


  1. 对象的类型不是 shared_ptr< x> shared_ptr_my_pimpl ;它只是假装是一个 shared_ptr

  2. 你不能得到 my_pimpl * my_pimpl& 它是一种不同的类型,只是表现相同。



2。从接口派生



使用所有相关函数pure virtual创建一个接口 my_pimpl_interface 。从此接口派生 my_pimpl my_pimpl :: impl (您的pimpl实现类)。添加一个函数 make_shared_my_pimpl ,它返回 shared_ptr< my_pimpl_interface> my_pimpl :: impl 。现在可以引用plain对象和shared_ptr对象作为 my_pimpl_interface&



缺点:


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


In this question I asked "pimpl: shared_ptr or unique_ptr" I've been convinced that the proper usage of the pimpl idiom is to use a unique_ptr, not a shared_ptr. It should act to the user as if there is no pointer at all, whereas quite clearly the shared_ptr introduces aliasing upon copying, which definitely acts like a pointer.

So, lets say a user wants to create a shared_ptr to my pimpl object (say if they want actually want multiple aliases to it). For example:

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

That would result in a shared_ptr pointing to a unique_ptr pointing to my implementation.

It would be nice if I could achieve something like the following:

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

but with somehow getting rid of the pointer to pointer, whilst still maintaining the implementation hiding of pimpl.

Any ideas how to achieve this (I'm happy to change the line (2) and obviously my_pimpl, but want lines (3) and (4) to stay the same).

解决方案

There are a number of possible approaches depending on your constraints.

1. Create your own shared_my_pimpl class

Create a class shared_my_pimpl which has the same interface as my_pimpl but internally uses a shared_ptr instead of a unique_ptr. Now create a class shared_ptr_my_pimpl which holds a shared_my_pimpl and has an operator-> which returns a pointer to the shared_my_pimpl, so that you get -> notation instead of . notation for member access. You can add a function make_shared_ptr_my_pimpl to make it look more like shared_ptr usage.

Disadvantages:

  1. The type of the object is not shared_ptr<x> but shared_ptr_my_pimpl; it's just pretending to be a shared_ptr.
  2. You can't get a my_pimpl* or my_pimpl& to the object; it's a different type which just behaves the same.

2. Derive from an interface

Create an interface my_pimpl_interface with all relevant functions pure virtual. Derive both my_pimpl and my_pimpl::impl (your pimpl implementation class) from this interface. Add a function make_shared_my_pimpl which returns a shared_ptr<my_pimpl_interface> to a my_pimpl::impl. You can now refer to both the plain object and the shared_ptr object as my_pimpl_interface&.

Disadvantages:

  1. By making all functions virtual you incur an extra indirection in calling them, which may have been what you were trying to avoid. Your standard my_pimpl object will also pay this overhead.

这篇关于pimpl:使用pimpl避免指针指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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