可能重复:
return type in c++
#include<iostream>
int& fun();
int main()
{
int p=fun();
std::cout<<p;
return 0;
}
int & fun()
{
int a=10;
return &a;
}
为什么这段代码会给出错误,错误:invalid initialization of non-const reference of type 'int&' from a temporary of type 'int*'
..实际上我不清楚临时性,即它们何时被创建以及何时被销毁。所以,请在某种程度上解释临时性
答案 0 :(得分:8)
&a
生成一个临时的,不能绑定到非const引用。
此外,您的代码有几个缺陷。
1)&a
的类型为int*
,而您通过引用返回,int &
。类型不匹配。
2)即使您在return语句中将&a
更改为a
,您的代码仍然无效,因为通过引用返回本地变量,然后使用结果是UB。
来自临时
的非const引用的初始化无效C ++不允许将临时值绑定到非常量引用。
例如你不能做这样的事情
int &x = 5;
因为临时int(5)
将在其结尾处被销毁。但是,对const的引用可以从临时文件初始化,即可以安全地编写
const int &x = 5;
在这种情况下,将临时值附加到const-reference会延长其生命周期。当x
被摧毁时,它就会被破坏。
答案 1 :(得分:1)
#include<iostream>
int& fun();
int main()
{
int p=fun();
std::cout<<p;
return 0;
}
int & fun()
{
int a=10;
return a; //Return a not &a
}
错误invalid initialization of non-const reference of type 'int&' from a temporary of type 'int*'' is because you are returning
&amp; a and not
a`。
上面的代码会正确编译,但它有一个严重的缺陷。
它返回对函数中临时堆栈变量的引用,一旦函数返回所有堆栈变量因堆栈展开而被销毁,最终你会指向一个不包含有效值的地址位置或你期望的值。
你应该总是避免在堆栈上返回对本地对象的引用指针!
正确的方法是:
#include<iostream>
int* fun();
int main()
{
int *p =fun();
std::cout<< *p;
delete p; //delete dynamically allocated memory else memory leak
return 0;
}
int* fun()
{
int *a = new int; //allocate dynamic memory
*a = 10;
return a;
}
答案 2 :(得分:0)
您不希望从&a
返回fun
,因为a
已在堆栈上分配,并且无法保证在fun
返回后保留其值。
如果您希望值继续存在,则需要使用new
或malloc
来获取堆分配的内存(之后再delete
或free
) fun
返回。通常在函数中声明的所有变量(例如int foo
)都驻留在其堆栈帧中。
答案 3 :(得分:0)
因为变量a是在堆栈上分配的,一旦函数返回就会消失,只留下一个虚假地址的引用。
答案 4 :(得分:0)
首先,&a
表示“a
的地址”。所以你实际上并没有在那里返回int
引用;你正在返回指针。
在任何一种情况下,您都应该a
分配new
,然后分配delete
,否则您将遇到未定义的行为。
答案 5 :(得分:0)
您的函数的返回类型是int&
。 foo
&a
(地址)中的表达式为int*
。要获得int&
类型,您必须使用表达式*&a
。这样做是取a
的地址然后取消引用它,导致引用而不是指针。注意:将引用(或指针)返回到非静态本地变量是不明确的并且将导致未定义的行为(最好的情况:您无法可靠地依赖于该值。最坏情况:您的硬盘驱动器是重新格式化)。
在这种情况下,您基本上有两个选项:将函数的签名更改为int foo()
,或将a
中的本地声明更改为static int a
和return语句只是return a;
。请注意,将a
更改为静态将使该函数成为非租用且非线程安全的。