正在返回常量引用

Returning const reference

本文关键字:引用 常量 返回      更新时间:2023-10-16

我对返回const引用到临时库的函数的声明有些困惑。

在以下代码中

#include <string>
#include <iostream>
using namespace std;
const string& foo() { 
    return string("foo"); 
}
string bar() { 
    return string("bar"); 
}
int main() {
    const string& f = foo();
    const string& b = bar();
    cout << b;
}

方法foobar之间有什么区别?

为什么foo给我warning: returning reference to local temporary object [-Wreturn-stack-address]。临时文件的副本不是在const string& f = foo();上创建的吗?

string("foo")创建一个类型为std::string的对象,该对象在函数中本地包含值"foo"。此对象将在函数结束时销毁。因此,一旦代码离开该函数[1],返回对该对象的引用将是无效的。因此,在main中,永远不会有对该字符串的有效引用。如果您在foo中创建了一个局部变量,情况也是如此。

返回引用的全部意义在于,您不进行复制,初始化引用(string &f = foo()是初始化)不会创建原始对象的副本,只是对同一对象的另一个引用[当代码返回main时,该引用已经无效]。对于许多事物,引用可以被视为"同一事物的不同名称"。

引用对象(换句话说,"别名"所指的实际对象)的生存期应始终长于引用变量(在这种情况下为f)。

bar的情况下,代码将作为return string("bar");的一部分进行复制,因为您在返回该对象时没有获取其引用——换句话说,通过复制对象,这样就可以了。

[1] 学究般地,当仍然在函数中时,但在您在函数中编写的代码结束后,在编译器引入的代码中,处理在函数中创建的对象的破坏。

const string& f = foo(); 上不是临时创建的副本吗

你从哪里听到的?

const添加到引用中通常可以将初始化它的临时的生存期延长到引用本身的生存期。从来没有副本。

但这里的情况并非如此。绑定到引用的对象在函数末尾超出了作用域,并且优先于其他对象。

您正在返回一个悬空引用;时期

为什么foo给我警告:返回对本地临时的引用object[-Wreturn堆栈地址]。

您正在foo()中创建一个临时字符串对象,并返回对该对象的引用,该引用将立即超出范围(悬空引用)

const string& foo() { 
    return string("foo"); // returns constant reference to temporary object
}                         // object goes out of scope

bar()完全不同:

string bar() {            
    return string("bar"); // returns a copy of temporary string
}
...
const string& b = bar();  // reference an rvalue string

方法foo和bar之间的区别是什么?

foo()返回常量(悬空)引用,而bar()返回临时字符串对象的副本。

在这两种情况下,都会在堆栈上初始化和分配字符串对象。从函数返回后,包含它的内存段变得不相关,并且它的内容可能被覆盖。

功能之间的区别:bar函数返回在其中创建的字符串实例的副本。

foo函数返回对在其内部创建的字符串实例的引用。换句话说,它返回一个指向其返回值的隐式指针,该指针位于临时内存段中,这就是发出警告的原因。