我正在使用一个库,其中包含许多使用 PIMPL 成语构建的类。在我看来,我发现不好的是,这些类是使用std::shared_ptr
实现的。这意味着对象实际上是“隐式共享”的。我的问题是:这是实施PIMPL的正确方法吗?或PIMPL和“隐式共享”是两种不同的习语,因此默认情况下不应该混合使用?处理复制语义的正确方法是什么?
答案 0 :(得分:5)
IMO,实施pimpl的正确方法是使用std::unique_ptr
。
它的效率更高,pimpl对象应该由可见类唯一拥有,而不是共享(并且你不必为复制语义而烦恼)。
PIMPL和"隐式共享"确实是两种不同的习语。
如果您仍然必须使用std::shared_ptr
进行pimpl,则必须明确定义复制分配操作(因为编译器无法生成正确的操作)。
答案 1 :(得分:0)
正如投币币所说,使用unique_ptr而不是shared_ptr。如果要使类可复制,可以始终在可见类的复制构造函数中调用pimpl对象的复制构造函数。
class A {
class impl;
std::unique_ptr<impl> pimpl;
public:
A(int x);
A(A const& old);
...
};
实现:
class A::impl {
int x;
public:
impl(int x)
: x(x) {}
impl(impl const& old)
: x(old.x) {}
};
A::A(int x)
: pimpl(std::make_unique<impl>(x)) {}
A::A(A const& old)
: pimpl(std::make_unique<impl>(*old.pimpl)) {}