PIMPL习语和复制语义

时间:2016-01-27 10:30:54

标签: c++ deep-copy pimpl-idiom

我正在使用一个库,其中包含许多使用 PIMPL 成语构建的类。在我看来,我发现不好的是,这些类是使用std::shared_ptr实现的。这意味着对象实际上是“隐式共享”的。我的问题是:这是实施PIMPL的正确方法吗?或PIMPL和“隐式共享”是两种不同的习语,因此默认情况下不应该混合使用?处理复制语义的正确方法是什么?

2 个答案:

答案 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)) {}