首页 > 解决方案 > Pimpl 成语和交换

问题描述

我有几个基于 PIMPL 习惯用法的类(其中 aunique_ptr指的是实际的实现结构)。

我没有添加friend swap函数(如此所述),因为据我所知,该标准std::swap使用移动语义可以很好地换出unique_ptrs. 到目前为止,一切都很好。

Effective C++但是,我读到( Scott Meyers 在第 25 条中说的有点过时:

但是,默认的交换实现可能不会让您兴奋。它涉及复制三个对象:a 到 temp、b 到 a 和 temp 到 b。[...] 对于某些类型,默认交换让您走上快车道到慢车道。这些类型中最重要的是那些主要由指向包含真实数据的另一种类型的指针组成的类型。这种设计的一个常见表现形式是“pimpl”习语。

之后他还建议专攻std::swap

我的问题是这是否仍然适用于 C++11。似乎 C++11swap对 pimpl'd 类工作得很好。我知道添加 afriend swap允许 STL 使用依赖于参数的查找等,但我更喜欢让我的类尽可能精简。

标签: c++c++11swapunique-ptrpimpl-idiom

解决方案


我的问题是这是否仍然适用于 C++11。

只是程度要小得多。

由于在 C++11 中引入了移动语义,通用交换不再复制,而是移动。

移动通常更接近于最佳交换实现,以至于人们通常不需要费心编写自定义实现。尽管它可能接近最优,但在许多情况下(包括 PIMPL 案例,如DanielLangr 所示),自定义实现可能会更好。可以通过测量性能来确定编写自定义代码是否足够快以有益。


推荐阅读