Effective C++ 条款 20:宁以 pass-by-reference-to-const 替换 pass-by-value
文章目录
- 条款 20:宁以 pass-by-reference-to-const 替换 pass-by-value
- 核心思想
- 优势
- 示例代码
- 特例:内置类型和小型对象
- 结论
条款 20:宁以 pass-by-reference-to-const 替换 pass-by-value
核心思想
C++ 默认以 pass-by-value 方式传递对象至函数。这意味着:
- 函数参数是调用时实际实参的副本(通过拷贝构造函数创建)。
- 函数返回的对象也是返回值的副本。
然而,这种方式在处理复杂对象时可能引发性能问题,甚至导致 切割问题 (slicing problem)。因此,建议对非内置类型采用 pass-by-reference-to-const。
优势
-
避免不必要的拷贝
- 通过引用传递对象,避免了拷贝构造函数的调用,提升性能。
-
避免切割问题
- 切割问题发生在传递一个派生类对象时。如果使用
pass-by-value
,只会复制基类部分,导致多态性丢失。pass-by-reference-to-const
则能完整保留对象的类型信息。
- 切割问题发生在传递一个派生类对象时。如果使用
-
可读性与安全性
const
限定保证了参数在函数内部不会被修改,增强代码安全性和可读性。
示例代码
// Pass-by-reference-to-const 示例 void printNameAndDisplay(const Window& w) { std::cout << w.name(); w.display(); }
在上例中,通过 const Window&
传递对象,避免了调用 Window
的拷贝构造函数,同时确保 w
在函数中不可修改。
特例:内置类型和小型对象
- 对于 内置类型(如
int
,double
,char
)以及 STL 的迭代器和函数对象,pass-by-value
更适合:- 内置类型的拷贝开销很低。
- 使用引用可能会增加间接访问的成本。
// Pass-by-value 示例 void processValue(int x); // 推荐 void advanceIterator(std::vector<int>::iterator it); // 推荐
结论
- 对于非内置类型,优先使用 pass-by-reference-to-const。
- 对于内置类型和小型对象,优先使用 pass-by-value。
- 这种策略既能提升代码性能,又能避免潜在问题(如切割问题)。