差别
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
public:it:cplusplus:effective_modern_cplusplus [2022/07/06 12:03] – [章节3. 转向现代C++] oakfire | public:it:cplusplus:effective_modern_cplusplus [2024/11/06 15:51] (当前版本) – [章节5. 右值引用、移动语义和完美转发] oakfire | ||
---|---|---|---|
行 101: | 行 101: | ||
=== » 条目12. 声明覆盖函数时,使用修饰词 override === | === » 条目12. 声明覆盖函数时,使用修饰词 override === | ||
* 区分覆盖和重载的区别。 | * 区分覆盖和重载的区别。 | ||
- | * c++11 比 c++98 对虚函数覆盖多了一条限定:覆盖函数的引用限定词必须与基类相同。 | + | * c++11 比 c++98 对虚函数覆盖多了一条限定:覆盖函数的引用限定词必须与基类相同。<code cpp> |
+ | class Widget { | ||
+ | public: | ||
+ | … | ||
+ | void doWork() &; | ||
+ | void doWork() &&; | ||
+ | }; | ||
+ | … | ||
+ | Widget makeWidget(); | ||
+ | Widget w; // normal object (an lvalue) | ||
+ | w.doWork(); | ||
+ | makeWidget().doWork(); | ||
+ | </ | ||
* '' | * '' | ||
=== » 条目13. 优先使用 const 迭代器 const_iterator === | === » 条目13. 优先使用 const 迭代器 const_iterator === | ||
行 170: | 行 182: | ||
* 和'' | * 和'' | ||
=== » 条目20 使用 std:: | === » 条目20 使用 std:: | ||
- | * '' | + | * '' |
- | * '' | + | auto spw = std:: |
- | * '' | + | std:: |
+ | spw = nullptr; | ||
+ | wpw.reset(); | ||
+ | </ | ||
+ | * '' | ||
+ | * '' | ||
std:: | std:: | ||
std:: | std:: | ||
行 180: | 行 197: | ||
* 观察者列表:被观察者不关心观察者的死活,观察者注销不需要关心被观察者的列表注销; | * 观察者列表:被观察者不关心观察者的死活,观察者注销不需要关心被观察者的列表注销; | ||
* 避免std:: | * 避免std:: | ||
+ | === » 条目21 比起new, 优先使用 std:: | ||
+ | * '' | ||
+ | * 使用new 的版本'' | ||
+ | * 考虑这个代码< | ||
+ | processWidget(std:: | ||
+ | </ | ||
+ | - 执行 new Widget | ||
+ | - 执行 computePriority() | ||
+ | - 构造 std:: | ||
+ | * 此时,如果第二步 执行computePriority() 时产生了异常导致第三步未执行,那么第一步的 new 就产生了泄露。 | ||
+ | * 所以,如果使用 new 方式,应把 new 结果直接传递给智能指针构建,确保这中间没有其它语句。 | ||
+ | * '' | ||
+ | * 不适合使用 '' | ||
+ | - 需要自定义删除器; | ||
+ | - 希望用花括号初始化。 | ||
+ | * 不建议使用 '' | ||
+ | - 有自定义内存管理的类; | ||
+ | - 特别关注内存的系统; | ||
+ | - 非常大的对象并且 '' | ||
+ | | ||
+ | === » 条目22 使用 Pimpl 惯用法时,定义特制成员函数需要放在实现文件里=== | ||
+ | * **Pimpl**(pointer to implementation)惯用法,为了缩减编译时间而减少头文件依赖 | ||
+ | * 对于 '' | ||
+ | // 以下都在实现文件 widge.cpp 中: | ||
+ | Widget:: | ||
+ | // 自定义析构导致拷贝与移动构造不能默认生成,手动生成需定义在实现文件 | ||
+ | Widget:: | ||
+ | Widget& Widget:: | ||
+ | </ | ||
+ | * '' | ||
+ | |||
+ | ==== 章节5. 右值引用、移动语义和完美转发 ==== | ||
+ | * **形参永远是左值**,即使它的类型是右值引用(参考上方导言第三行) | ||
+ | === » 条目23 理解 std::move 与 std:: | ||
+ | * '' | ||
+ | // std::move 的简单实现: | ||
+ | template< | ||
+ | decltype(auto) move(T&& | ||
+ | { | ||
+ | using ReturnType = remove_reference_t< | ||
+ | | ||
+ | }</ | ||
+ | * 如果想移动实参,就不要把实参声明为 '' | ||
+ | * '' | ||
+ | * '' | ||
+ | === » 条目24 区分通值引用与右值引用 === | ||
+ | * 通值引用,两种情况: | ||
+ | * 函数模板参数为 '' | ||
+ | * 变量声明为 '' | ||
+ | * 如果类型声明格式不是标准的'' | ||
+ | void f(Widget&& | ||
+ | Widget&& | ||
+ | auto&& | ||
+ | template< | ||
+ | void f(std:: | ||
+ | template< | ||
+ | void f(T&& | ||
+ | </ | ||
+ | * 通值引用如果是被右值初始化,那么就转为右值引用,左值则转为左值引用(详见类型推导)。 | ||
+ | === » 条目25 std::move 使用在右值引用,std:: | ||
+ | * 要利用形参的右值性时,右值引用的形参使用 '' | ||
+ | * 一个函数内想多次利用同一个对象的右值性时,只在最后一次使用 '' | ||
+ | * 按值返回的函数要返回右值引用或通值引用时,同样使用 '' | ||
+ | * 由于标准规定编译器存在返回值优化(return value optimization,RVO)以及在不优化场景下将 '' | ||
+ | |||
+ | === » 条目26 避免重载通值引用 === | ||
+ | * 相比 '' | ||
+ | template< | ||
+ | void logAndAdd(int idx){} // overload_func | ||
+ | |||
+ | short index; | ||
+ | logAndAdd(index); | ||
+ | </ | ||
+ | * 完美转发构造函数尤其如此,因为对于非const左值来说,它们通常比复制构造函数(复制构造函数参数声明为const)更匹配,而且它们可以劫持派生子类调用基类的复制与移动构造函数,转而让子类调用完美转发构造函数。 | ||
+ | === » 条目27 熟悉「重载通值引用」之外的替代方法 === | ||
+ | |||
==== 翻译对照 ==== | ==== 翻译对照 ==== | ||
<WRAP tablewidth 50% > | <WRAP tablewidth 50% > | ||
- | ^ 英 | + | ^ 英 ^ 汉 ^ 备注 |
- | | argument | + | | argument |
- | | parameter | + | | parameter |
| basic guarantee | | basic guarantee | ||
- | | strong guarantee | + | | strong guarantee |
- | | built-in pointer | + | | built-in pointer |
- | | raw pointer | + | | raw pointer |
- | | universal reference | + | | universal reference |
- | | scoped enums | 限定域枚举 | + | | scoped enums | 限定域枚举 |
| unscoped enums | 非限定域枚举 | | unscoped enums | 非限定域枚举 | ||
- | | forward-declared | + | | forward-declared |
- | | override | + | | override |
- | | maximally | + | | overload |
+ | | maximally | ||
| special member function | | special member function | ||
- | | | + | | |
- | | | + | | |
- | | | + | | |
- | | | + | | |
</ | </ |