正在返回常量引用
Returning const reference
我对返回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;
}
方法foo
和bar
之间有什么区别?
为什么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
函数返回对在其内部创建的字符串实例的引用。换句话说,它返回一个指向其返回值的隐式指针,该指针位于临时内存段中,这就是发出警告的原因。
- 什么时候在C++中返回常量引用是个好主意
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 为什么我可以通过引用修改常量返回
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- 将常量指针引用绑定到非常量指针
- 通过常量引用传递参数的矩阵模板类
- 按值捕获引用时出现非常量
- 在C++中使用非常量引用作为常量
- 具有常量引用参数的函数模板专用化
- 多个"常量引用"变量可以共享同一个内存吗?
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 为什么按值传递QStringView比引用常量更快?
- 通过引用常量函数调用另一个类的非常量函数
- 构造常量对象与引用常量对象
- 引用“常量value_type”时出错
- 为什么可以在 for 语句中重新分配引用常量
- 程序反馈:命名循环索引和引用常量数据
- 堆还是栈?在c++中函数调用中引用常量字符串时
- 为什么常量结构数组在按名称引用常量结构时不放在 .rodata 中?
- 为什么编译器允许在函数中发送对迭代器的引用,该函数引用常量迭代器