是否有任何理由不使用 pimpl 在 C++ 中实现移动支持?

问题描述

显然,pimpl 不是严格必要的,但是如果类是按照“正常”方式设计的,那么移动似乎不会给您带来全部预期的好处:移动是应该的要便宜;特别是,它应该比复制快得多;成本不应随着“真实”内部数据的数量而“扩大”。理想情况下,成本应该是 O(1)。

显然,如果您使用 pimpl,您每次都能以最少的努力和最大的可靠性获得这种速度优势(感谢 = default)。那么,当您想要移动物体时,是否有任何理由不只是在整个地方做 pimpl 呢?

(我假设您可以在应用程序中使用堆,因为这显然排除了 pimpl。)

解决方法

在重要的时候移动比复制便宜——对于那些移动本身很昂贵的类型,主要是由于内部分配堆内存,如 std::string 或 std::vector。复制一个有 10 个“整数”的类,它无论如何都相对便宜,因此对这种类型的类进行更快的“移动”操作几乎没有什么好处。

虽然您认为 pimpl 在任何情况下都会加快移动速度是正确的,但它也为对象的创建(通过必须在堆上分配内部“pimpl”对象)以及使用(通过现在为任何外部调用提供额外的间接调用。我个人认为这不是使用 pimpl 的唯一原因是为了加快移动速度 - 除非移动是您特定用例中的主要瓶颈。

就我个人而言,我宁愿走另一轮 - 如果您有一个非常大的对象,仅由无法有效移动的“琐碎”类型组成,并且您希望该对象快速移动,那么只需将对象存储在堆栈 (std::unique_ptr)。这样,您就不会将 pimpl 的开销强加给类的每个用户,同时在您需要时仍然可以快速移动。

,

对于 pimpl,唯一的类数据成员是一个指针。在这种情况下,移动支持很便宜,因为复制该指针比复制它指向的大型数据结构便宜。

但是如果类有几个指向大型结构的指针,同样的推理也适用。或者一个指向大结构的指针和一些小的非指针。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...