为什么返回对自动变量的引用有效
Why does returning a reference to a automatic variable work?
我目前正在阅读关于C++的文章,并且我读到当使用引用返回时,我应该确保我不会返回对函数返回时将超出范围的变量的引用。
那么,为什么在Add
函数中,对象cen
是通过引用返回的,并且代码工作正常呢?!
这是代码:
#include <iostream>
using namespace std;
class Cents
{
private:
int m_nCents;
public:
Cents(int nCents) { m_nCents = nCents; }
int GetCents() { return m_nCents; }
};
Cents& Add(Cents &c1, Cents &c2)
{
Cents cen(c1.GetCents() + c2.GetCents());
return cen;
}
int main()
{
Cents cCents1(3);
Cents cCents2(9);
cout << "I have " << Add(cCents1, cCents2).GetCents() << " cents." << std::endl;
return 0;
}
我在Win7上使用CodeBlocks IDE。
这是未定义的行为,它似乎可以正常工作,但它可以随时中断,您不能依赖此程序的结果。
当函数退出时,用于保存自动变量的内存将被释放,引用该内存将无效。
3.7.3
第1段中的C++标准草案说:
显式声明为register或未显式声明的static或extern的块作用域变量具有自动存储持续时间这些实体的存储将持续到创建它们的块退出为止
可能发生的情况(同样,对于UB,任何事情都会发生)是,因为在调用Add
之后,您没有调用任何其他东西,没有任何东西覆盖cen
所在的内存,所以旧值仍然存在。话虽如此,你不能指望这种情况总是发生。
您应该执行memcpy以将返回的对象复制到堆中。尽管代码可以工作,但当返回超出范围的对象时,行为是未定义的。当代码很小时,它可能总是有效的,因为当函数返回时,函数占用的堆栈部分将不会被清除,并且由于函数中的局部变量将被分配空间,因此您获得的值(通常)包含您期望的值。但是,当您有多个函数相互调用,并且程序变得很大时,您的程序将开始产生未定义的行为。有时甚至可能出现断层。
相关文章:
- 在函数内创建的对象的范围 - 如果在函数外部存储和访问引用,它们是否有效?
- 为什么在引用指针时将 const 放在 & 符号的左侧有效,而在右侧则无效?
- C++/11 auto 关键字是在更有效时推导参数进行按引用传递,还是始终按值传递?
- 为什么此代码片段有效?如何取消引用空点?
- 为什么 lambda nullptr 取消引用在这种情况下有效?
- 为什么我在函数中使用引用并通过引用返回它仍然有效?
- 返回一个引用C++中另一个类对象的对象的有效方法
- 调整大小后保持对矢量元素的引用有效
- 为什么此元组到引用元组 (std::tie) 转换有效?
- 自定义类型转换运算符在转发引用上调用时不起作用(当对象按值传递时有效)
- std::shared_ptr<std::string const> 可以作为引用计数的不可变字符串的有效实现吗?
- Eigen:引用 ArrayWrapper 的有效方法
- 如果不允许我分配 rvalues 来引用为什么以下代码片段有效,这在内部如何工作?
- 如果 null 不是有效值,则使参数成为引用而不是指针
- 将浮点数分配给字符串引用有效 - 为什么
- 如何检测ptr在引用超出范围后是否仍在引用有效引用
- 为什么通过右值初始化非常量引用有效(在 C++11 中)
- 为什么返回对自动变量的引用有效
- 在 C++ 中初始化引用不起作用,但初始化 const 引用有效,为什么?
- 为什么指向释放内存的引用有效