c++ - Pimpl 成语和交换
问题描述
我有几个基于 PIMPL 习惯用法的类(其中 aunique_ptr
指的是实际的实现结构)。
我没有添加friend
swap
函数(如此处所述),因为据我所知,该标准std::swap
使用移动语义可以很好地换出unique_ptr
s. 到目前为止,一切都很好。
Effective C++
但是,我读到( Scott Meyers 在第 25 条中说的有点过时:
但是,默认的交换实现可能不会让您兴奋。它涉及复制三个对象:a 到 temp、b 到 a 和 temp 到 b。[...] 对于某些类型,默认交换让您走上快车道到慢车道。这些类型中最重要的是那些主要由指向包含真实数据的另一种类型的指针组成的类型。这种设计的一个常见表现形式是“pimpl”习语。
之后他还建议专攻std::swap
。
我的问题是这是否仍然适用于 C++11。似乎 C++11swap
对 pimpl'd 类工作得很好。我知道添加 afriend
swap
允许 STL 使用依赖于参数的查找等,但我更喜欢让我的类尽可能精简。
解决方案
我的问题是这是否仍然适用于 C++11。
只是程度要小得多。
由于在 C++11 中引入了移动语义,通用交换不再复制,而是移动。
移动通常更接近于最佳交换实现,以至于人们通常不需要费心编写自定义实现。尽管它可能接近最优,但在许多情况下(包括 PIMPL 案例,如DanielLangr 所示),自定义实现可能会更好。可以通过测量性能来确定编写自定义代码是否足够快以有益。
推荐阅读
- node.js - 如何在 Opsworks (AWS) 中使用 Apollo 服务器包部署 Nodejs 应用程序
- unit-testing - 模拟 perl 反引号的返回码和输出
- javascript - 如何在 PF 6 中禁用 p:progressBar 过渡动画
- react-native - 无法在 Android 上打开键盘,同时出现模态
- php - 获取具有 id 的多维数组中的最高日期
- javascript - 如何将 JS 库合并到我的 NPM 构建脚本中?
- spring-boot - Kotlin 的导入注释中预期的名称
- javascript - 导入 sendgrid 邮件时它不起作用
- python - 决定重建时忽略一些标志更改
- ios - 将子视图定位在圆形视图的边缘