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)) {}
我正在使用一个库,其中包含大量使用 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)) {}