Effective C++ 条款21:必须返回对象时,别妄想返回其 reference
绝不返回 pointer 或 reference 指向一个 local stack 对象,或返回 reference 指向一个 heap-allocated 对象,或返回 pointer 或 reference 指向一个 local static 对象而有可能同时需要多个这样的对象。
一、引言:从性能优化误区说起
当你理解了按值传递可能带来的性能开销(条款20),许多人会化身为"优化十字军",誓要清除所有隐藏的拷贝成本。返回对象?太浪费了!返回引用才是高手风范!
停! 这种思维往往适得其反。条款21正是要纠正这个危险的误区——当函数必须返回新对象时,老老实实返回对象值,别妄想用 reference 来"优化"。
二、返回局部对象引用:悬空引用的噩梦
2.1 经典错误示例
#include <iostream>
#include <string>
#include <vector>
class ExpensiveResource {
public:
ExpensiveResource(const std::string& name) : name_(name) {
data_.resize(1000, 42);
std::cout << "构造: " << name_ << std::endl;
}
~ExpensiveResource() {
std::cout << "析构: " << name_ << std::endl;
}
void use() const {
std::cout << "使用资源: " << name_ << std::endl;
}
private:
std::string name_;
std::vector<int> data_;
};
// ❌ 致命错误:返回局部对象的引用
const ExpensiveResource& createResourceWrong() {
ExpensiveResource local("局部资源");
return local; // local 在函数结束时销毁!
}
2.2 问题剖析
| 返回方式 | 问题 | 后果 |
|---|---|---|
| 返回局部 stack 对象引用 | 函数返回后对象销毁 | 悬空引用(Dangling Reference),未定义行为 |
| 返回临时对象引用 | 临时对象立即销毁 | 同上,甚至更隐蔽 |
| 返回堆对象引用 | 调用者无法正确释放 | 内存泄漏 |
| 返回 static 对象引用 | 多线程/多实例冲突 | 线程安全问题,数据竞争 |
// ❌ 错误2:返回临时对象引用
const ExpensiveResource& createTempWrong() {
return E


756

被折叠的 条评论
为什么被折叠?



