PIMPL习语和复制语义

PIMPL idiom and copy semantic

我正在使用一个库,其中包含大量使用 PIMPL 习语构建的 类。在我看来,我发现不好的是那些 类 是使用 std::shared_ptr 实现的。这意味着对象实际上是 "implicitly shared"。我的问题是:这是实施 PIMPL 的正确方法吗?或者 PIMPL 和 "implicitly shared" 是两个不同的习语,因此默认情况下不应混合使用?处理复制语义的正确方法是什么?

IMO,实现 pimpl 的正确方法是使用 std::unique_ptr。 它更高效,pimpl 对象应该由可见的 class 唯一拥有,而不是共享(并且您不必为复制语义而烦恼)。

PIMPL 和 "implicitly shared" 确实是两个不同的成语。

如果您仍然需要对 pimpl 使用 std::shared_ptr,那么您将必须显式定义复制赋值操作(因为编译器将无法生成正确的操作)。

正如 coincoin 所说,使用 unique_ptr 而不是 shared_ptr。如果你想让你的 class 可复制,你总是可以在你可见的 class.

的复制构造函数中调用你的 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)) {}