返回一个引用并返回一个值
Returning a reference and returning a value
我不太确定我是否理解了当我们返回一个局部随机变量的引用时为什么会出现问题。假设我们有这个例子。
int *myFunc() {
int phantom = 4;
return &phantom;
}
然后通常的参数是,当使用函数时,变量phantom
的内存在代码行int phantom = 4;
执行后不再可用,因此它不能返回(至少这是我迄今为止所理解的)。另一方面,对于函数
int myFunc() {
int phantom = 4;
return phantom;
}
返回整型变量phantom
的值。(我认为该值的返回是对变量phantom
的底层指针的解引用)。
我错过了什么??为什么在第一种情况下有一个编译错误,在第二种情况下一切工作??
第一个不是返回引用,而是返回指针。指向局部变量的指针,一旦函数结束,该局部变量就会超出作用域,给您留下一个指向不再存在的变量的指针。这就是为什么你得到一个编译器警告(通常不是一个实际的错误)。
第二段代码复制该值。一旦return
语句结束,函数内部的局部变量将永远不需要被引用或使用。
你不会错过太多。只有在第一种情况下,不会有编译器错误。
[…在执行代码行int phantom = 4后,变量phantom的内存不再可用;所以不能返回
不,它可以返回,编译器可能会发出警告,但不会出错。然而,你不应该!!
顺便说一句,内存是可用的,但是在函数返回后(而不是在int phantom = 4;
行之后)访问它是未定义的行为。
第二种情况:
你想得太复杂了。从函数返回值可以通过使用指针来实现,但这是一个实现细节。这里唯一需要关心的是返回的是值。所以第二种情况没有问题我将该值的返回视为变量phantom
的底层指针的解引用
我不太确定我是否理解了为什么会有问题返回一个局部随机变量
的引用。
因为c++标准规定,如果你使用这样的函数,它是未定义行为,并且你希望在程序中避免未定义行为。你的程序所做的应该由c++语言的规则来决定,而不是随机的。
注意,返回的是指针而不是引用。但在这两种情况下都是未定义的行为。
那么通常的参数是,当使用函数时,内存变量
phantom
的值在执行后不再可用代码行int phantom = 4;
,所以它不能返回(至少这个
这是一个以实现为中心的观点,可以帮助您理解问题。
然而,区分程序的可观察行为和编译器产生该行为的内部技巧是很重要的。你甚至不知道某个变量是否占用了内存。考虑到"as-if"规则和编译器优化,即使定义了行为,整个函数也可能被删除。这只是幕后可能发生的事情的一个例子。
但是,无论如何,这是未定义的行为,所以任何事情都可能发生。
问题是,那么,为什么c++标准没有为这种情况定义一种行为,当你返回一个像这样的指针,然后尝试访问指针?答案是,这没有意义。由局部变量phantom
命名的对象在函数返回时结束其生命。因此,您将有一个指向不再存在的东西的指针,但它仍然是int*
,并且解引用非nullptr
int*
应该产生int
。这是一个矛盾,而c++标准根本懒得解决这种无意义的情况。
注意这个观察结果是基于c++语言规则的,不是关于编译器实现问题。
为什么在第一种情况下有编译错误,而在第二种情况下万一一切顺利??
这当然是一个警告,而不是错误,除非你的编译器选项使每个警告都变成错误。编译器不能拒绝代码,因为它不是病态的。
但是,在第一种情况下,你的编译器试图提供帮助,因为它想要阻止你创建一个具有未定义行为的程序。
在第二种情况下,行为不是未定义的。按值返回意味着由你想要返回的对象组成一个副本。在原始文件被销毁之前生成副本,然后调用方接收该副本。这不是毫无意义的,也不是矛盾的,所以这是安全的,明确的行为。
在第一种情况下,按值返回对您没有帮助,因为尽管指针本身被安全地复制,但其内容最终导致未定义行为。
第一个case
int* myFunc()
{
int phantom = 4;
return &phantom; // you are returning the address of phantom
} // but phantom will not "exist" outside of myfunc
不起作用,因为变量phantom
是一个局部变量,它只在myfunc
执行期间存在。之后,它就消失了。
你返回的是一个变量的地址,这个变量实际上将"不再存在"。
规则:永远不要返回指向局部变量的指针或引用
This is OK:
int myFunc()
{
int phantom = 4;
return phantom; // you are returning by value;
// it doesn't matter where phantom "lives"
}
int main()
{
int x = myFunc(); // the value returned by myFunc will be copied to x
}
尝试返回指针并对其解引用以获得值。
#include <iostream>
using namespace std;
int *myFunc()
{
int number = 4;
int *phantom = &number;
return phantom;
}
int main()
{
cout << myFunc() << endl; //0x....
cout << *myFunc() << endl; //4
return 0;
}
- 如何返回一个类的两个对象相加的结果
- 使用std::mt19937从字符串中返回一个随机单词
- PyRun_String返回一个NoneType对象
- 为什么我们要为avl树实现返回一个指向节点的指针,而不是void函数
- 返回一个带有 std::move 的对象并链接函数
- 为什么 C++ std::unordered_map 从 emplace/ 找到返回一个迭代器?
- C++:返回一个基于范围 for 循环迭代器,其中包含继承对象
- 函数可以应用于 std::optional,并返回一个可选值吗?
- readAll() 或 readAllStandardOutput() 在执行之前也返回一个空字符串
- Atmel Studio:返回一个包含数组的寄存器
- 返回一个计算了参数的函数
- 我有一个返回字符串向量的函数.它需要两个字符串,并且返回一个字符串中缺少的字符串
- 返回一个引用C++中另一个类对象的对象的有效方法
- 从类返回一个字符串 — 奇怪的行为
- 有没有一种方法可以从函数中返回一个新对象或对现有对象的引用
- 我正在尝试从 GMocked 类返回一个 rapidjson::值,但我似乎无法让它工作
- 实现一个函数,该函数将字符串作为输入并返回一个新字符串,辅音字母不替换为 "!"
- 错误 C4716"当事方::运算符+":必须返回一个值
- CStringArray::GetAt(int index) 返回一个 const. 为什么?
- 从system()调用G++会返回一个错误