在C++中返回引用

pan*_*ajt 6 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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

$ ./a.exe
Double = 46.5
String =
Run Code Online (Sandbox Code Playgroud)

sho*_*osh 16

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

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

string &getString(){
    string str = "Devil Jin";
    return str;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 实际上,我认为他说即使是双重警告也不会发出警告.因此编译器在两种情况下都被愚弄了.它与double一起使用的原因可能是因为堆栈上的h的位置没有被覆盖.试试这个:在主商店d中加倍然后调用其他几个函数,然后打印d.我打赌它不对劲.但在所有情况下,你所做的是"未定义的行为".那里有一个很好的教训:仅仅因为它给出了正确的答案并不意味着它以正确的方式完成.;) (6认同)

Eva*_*van 6

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