在C ++中返回引用

时间:2010-04-10 07:15:30

标签: c++ reference

考虑以下代码,我将返回double&string&。它在双精度的情况下工作正常,但在字符串的情况下则不行。为什么行为不同?

两个的情况下,编译器甚至不会抛出Warning: returning address of local variable or temporary,因为我正在返回引用。

#include <iostream>
#include <string>
using namespace std;


double &getDouble(){
    double h = 46.5;
    double &refD = h;
    return refD;
}

string &getString(){
    string str = "Devil Jin";
    string &refStr = str;
    return refStr;
}

int main(){
    double d = getDouble();
    cout << "Double = " << d << endl;

    string str = getString();
    cout << "String = " << str.c_str() << endl;

    return 0;
}
  

输出:

$ ./a.exe
Double = 46.5
String =

4 个答案:

答案 0 :(得分:16)

无论编译器做什么或不做什么,都不应该返回对局部变量的引用。编译器可能很容易被欺骗。你不应该将你的代码的正确性建立在一些可能没有被解雇的警告上。

这里没有触发的原因可能是你没有真正返回对局部变量的引用,而是返回一个对局部变量的引用的变量。编译器可能没有检测到这种更复杂的情况。它只检测如下内容:

string &getString(){
    string str = "Devil Jin";
    return str;
}

double的情况比较简单,因为它不涉及构造和破坏复杂对象,因此在这种情况下,编译器的流控制分析可能在检测错误方面做得更好。

答案 1 :(得分:6)

double的引用是指仍然在物理上在内存但不再在堆栈中的位置。你只是逃避它,因为内存还没有被覆盖。 double是一个原语,string是一个对象,并且有一个析构函数,当它超出范围时,可以将内部字符串清零为零长度。您拨打c_str()时没有收到垃圾的事实似乎支持这一点。

答案 2 :(得分:1)

GCC曾经有一个名为Named Returns的扩展程序,它允许您完成同样的事情,但是在函数外部分配了空间。不幸的是它不再存在了;我不确定他们为什么把它拿出来

答案 3 :(得分:0)

关于C ++的Dangling引用的经典案例。双变量不在调用堆栈上,而返回引用试图访问它,调用编译器来设置防护标志。但是,String具有显式的垃圾收集机制,使您的编译器可以忽略该场景。