我曾经认为返回引用很糟糕,因为我们返回的引用会引用一些垃圾值。但是这段代码有用(matrix
是一个类):
const int max_matrix_temp = 7;
matrix&get_matrix_temp()
{
static int nbuf = 0;
static matrix buf[max_matrix_temp];
if(nbuf == max_matrix_temp)
nbuf = 0;
return buf[nbuf++];
}
matrix& operator+(const matrix&arg1, const matrix&arg2)
{
matrix& res = get_matrix_temp();
//...
return res;
}
buf
在这里做什么以及它如何使我们免于垃圾值?
答案 0 :(得分:2)
buf
被声明为static
,这意味着它在函数调用之间保留了它的值:
static matrix buf[max_matrix_temp];
即。它不是在堆栈上创建的,因为int i = 0;
会是(一个非静态的局部变量),所以返回它的引用是完全安全的。
以下代码 是危险的,因为变量值的内存在堆栈上,所以当函数返回并且我们将堆栈向上移回上一个函数时,所有的内存预留功能的本地不再存在:
int * GetAnInt()
{
int i = 0; // create i on the stack
return &i; // return a pointer to that memory address
}
一旦我们返回,我们有一个指向堆栈内存的指针,运气不好,它会保留我们想要的值,因为它还没有被覆盖 - 但是引用是无效的,因为内存现在是当需要堆栈空间时可以免费使用。
答案 1 :(得分:0)
我看到任何地方都没有声明buf
,这意味着它不会超出函数返回的范围,所以没关系。 (它实际上看起来像是matrixbuf
,这也很好,因为它是static
)。
编辑:感谢R. Martinho Fernandes的猜测。当然它是matrix buf
,所以它使buf
静态数组在其中分配临时值以确保在函数返回时它不会被释放,因此返回值仍然有效。
答案 2 :(得分:0)
这是安全的,但非常危险。返回的参考
不能摇摆不定,但如果客户代码保留它,在未来的某个时刻,
当他的价值突然变为a时,客户感到非常惊讶
新的回报价值。如果你打电话给get_matrix_temp
以上
在单个表达式中max_matrix_temp
次,你最终会结束
也覆盖数据。
在std::string
之前的日子里,在使用printf
的代码中,我使用了这个
返回用户定义类型转换的技术,其中a
使用了"%s"
说明符,参数是对格式的调用
功能。同样,max_matrix_temp
是一个弱点:单一
格式化了我的类型的更多实例的printf
输出错误
数据。那时候这是一个坏主意,现在这是一个更糟糕的主意。