返回参考可以工作吗?

时间:2012-01-19 11:04:31

标签: c++

我曾经认为返回引用很糟糕,因为我们返回的引用会引用一些垃圾值。但是这段代码有用(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在这里做什么以及它如何使我们免于垃圾值?

3 个答案:

答案 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输出错误 数据。那时候这是一个坏主意,现在这是一个更糟糕的主意。