我一直在使用 pimpl 成语制作一些对象,但我不确定是使用 std::shared_ptr
还是 std::unique_ptr
。
我知道 std::unique_ptr
效率更高,但这对我来说不是什么大问题,因为这些对象无论如何都是相对重量级的,所以 std::shared_ptr
的成本超过 std::unique_ptr
相对较小。
我目前正在使用 std::shared_ptr
只是因为额外的灵活性。例如,使用 std::shared_ptr
允许我将这些对象存储在哈希图中以便快速访问,同时仍然能够将这些对象的副本返回给调用者(因为我相信任何迭代器或引用都可能很快变得无效)。
但是,这些对象实际上并没有被复制,因为更改会影响所有副本,所以我想知道也许使用 std::shared_ptr
并允许副本是某种反模式或坏事。
这个对吗?
原文由 Clinton 发布,翻译遵循 CC BY-SA 4.0 许可协议
绝对
unique_ptr
或scoped_ptr
。Pimpl
不是一种模式,而是一种习语,它处理编译时依赖和二进制兼容性。它不应影响对象的语义,尤其是在其复制行为方面。您可以在后台使用您想要的任何类型的智能指针,但它们 2 保证您不会意外地在两个不同的对象之间共享实现,因为它们需要有意识地决定复制构造函数和赋值运算符的实现。
它不是反模式,实际上是一种模式:Aliasing。您已经在 C++ 中使用了它,并带有裸指针和引用。
shared_ptr
提供额外的“安全”措施以避免死引用,但代价是额外的复杂性和新问题(注意会造成内存泄漏的循环)。与粉刺无关
如果您可以考虑某些状态,您可能需要查看 Flyweight 模式。