代码之家  ›  专栏  ›  技术社区  ›  pankajt

在C++中复制引用[复制]

  •  6
  • pankajt  · 技术社区  · 16 年前

    考虑下面的代码 double& 和A string& . 它在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 回复  |  直到 13 年前
        1
  •  16
  •   shoosh    16 年前

    无论编译器做什么或不做什么,都不应该返回对局部变量的引用。编译器很容易上当。您不应该将代码的正确性建立在某些可能尚未触发的警告上。

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

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

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

        2
  •  6
  •   Evan    14 年前

    提及 double 指物理上仍在内存中但不再在堆栈上的位置。你这样做只是因为内存还没有被覆盖。鉴于 双重的 是一个原始的 string 是一个对象,具有析构函数,当内部字符串超出范围时,析构函数可能会将其清除为零长度。事实上你不会从你的电话中得到垃圾 c_str() 似乎支持这一点。

        3
  •  1
  •   Michael Mrozek    16 年前

    gcc以前有一个名为 Named Returns 这让您可以完成相同的任务,但在函数之外分配了空间。不幸的是它已经不存在了;我不知道他们为什么要把它取出来

        4
  •  0
  •   user1938465    13 年前

    关于C++的悬空引用的经典案例。双变量不是调用堆栈,而返回引用是试图访问它,调用编译器设置保护标志。但是,字符串有显式的垃圾收集机制,允许编译器忽略该方案。