问题描述
显然,pimpl 不是严格必要的,但是如果类是按照“正常”方式设计的,那么移动似乎不会给您带来全部预期的好处:移动是应该的要便宜;特别是,它应该比复制快得多;成本不应随着“真实”内部数据的数量而“扩大”。理想情况下,成本应该是 O(1)。
显然,如果您使用 pimpl,您每次都能以最少的努力和最大的可靠性获得这种速度优势(感谢 = default
)。那么,当您想要移动物体时,是否有任何理由不只是在整个地方做 pimpl 呢?
(我假设您可以在应用程序中使用堆,因为这显然排除了 pimpl。)
解决方法
在重要的时候移动比复制便宜——对于那些移动本身很昂贵的类型,主要是由于内部分配堆内存,如 std::string 或 std::vector。复制一个有 10 个“整数”的类,它无论如何都相对便宜,因此对这种类型的类进行更快的“移动”操作几乎没有什么好处。
虽然您认为 pimpl 在任何情况下都会加快移动速度是正确的,但它也为对象的创建(通过必须在堆上分配内部“pimpl”对象)以及使用(通过现在为任何外部调用提供额外的间接调用。我个人认为这不是使用 pimpl 的唯一原因是为了加快移动速度 - 除非移动是您特定用例中的主要瓶颈。
就我个人而言,我宁愿走另一轮 - 如果您有一个非常大的对象,仅由无法有效移动的“琐碎”类型组成,并且您希望该对象快速移动,那么只需将对象存储在堆栈 (std::unique_ptr)。这样,您就不会将 pimpl 的开销强加给类的每个用户,同时在您需要时仍然可以快速移动。
,对于 pimpl,唯一的类数据成员是一个指针。在这种情况下,移动支持很便宜,因为复制该指针比复制它指向的大型数据结构便宜。
但是如果类有几个指向大型结构的指针,同样的推理也适用。或者一个指向大结构的指针和一些小的非指针。