在这个问题中,我问"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)行保持不变)。
答案 0 :(得分:2)
根据您的限制,有许多可能的方法。
创建一个类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
用法。
缺点:
shared_ptr<x>
,而是shared_ptr_my_pimpl
;它只是伪装成shared_ptr
。my_pimpl*
或my_pimpl&
;它是一种行为相同的不同类型。创建一个界面my_pimpl_interface
,其中所有相关功能都是纯虚拟的。从此接口派生my_pimpl
和my_pimpl::impl
(您的pimpl实现类)。添加一个函数make_shared_my_pimpl
,将shared_ptr<my_pimpl_interface>
返回给my_pimpl::impl
。您现在可以将普通对象和shared_ptr对象都称为my_pimpl_interface&
。
缺点:
my_pimpl
对象也将支付此开销。答案 1 :(得分:0)
您应该使用界面来实现此目的,因为您的班级用户可以选择是否要使用shared_ptr
或unique_ptr
。