考虑以下代码
int& func1() {
int x = 2;
return x;
}
int& func2(int &x) {
return x;
}
int main() {
int x = func1();
cout<<"\n : "<<x;
int y = 3;
x = func2(y);
cout<<"\n : "<<x<<"\n";
}
输出:
: 2
: 3
代码工作正常,但我对下面列出的内容几乎没有疑问:
在func1()中,我返回了一个non_reference变量&#34; x&#34;但是 return类型是对int的引用,所以如何转换 发生了什么以及&#34; x&#34;功能实际上正在返回。
在func1()&#34; x&#34;作为参考返回但是作为堆栈变量如何引用 可以返回x ,我的意思是它在完成后没有任何意义(我 我将这一点与逻辑相关联。函数不应返回其指针 内存以静态方式分配&#34;)。
在func1()中,它返回一个非参数变量&#34; x&#34;作为参考 到一个int和在func2()中它返回一个引用变量&#34; x&#34;如 参考int。 同时&#34; x&#34;是不同类型,但为什么 返回类型相同。。
我很困惑,因为我试图将C ++与c联系起来,因为一切都很清楚,但这主要是由于缺乏refrence变量的内存布局描述,所以如果有人能说明这一点那么它将会非常有帮助我
答案 0 :(得分:3)
在func1
中,你要归的是对某事的引用。这个内容是x
,它是func1
的本地内容,其生命周期在返回时结束。然后,在main
中,您分配引用变量的内容(x
func1
,它正在根据吃蒲公英)来初始化main
的本地变量x
。这是未定义的行为,这意味着允许程序将其解释为它想要的任何内容,格式化您的硬盘驱动器或任何东西。 (最有可能的是,func1
返回指向被调用堆栈帧的变量的指针,该变量可能仍然包含正确的值,因为当它们被下一个函数调用压碎时,为什么还要删除堆栈上的值呢? )无论如何,程序是否会与其他优化选项一起编译,它可能会给出另一个答案。
在func2
中,你要归的是对某事的引用。 x
引用的内容是main
y
引用的内容。然后,您为main
的{{1}}分配了引用变量的值x
。
关于引用的内存布局问题,在C中,指针是内存中的地址。期。无处可逃。在C ++中,引用是一种更高级别的机制,在这种机制中,您“引用某些东西”,“谈论某些东西”,“看起来就是我就在那里”。 它们完全可以作为普通指针实现。但作为一种语言概念,它们更容易被优化掉,因为它们是不可变的。 (一旦设置了引用,它就无法更改。它指的是某些内容 - 甚至是无效内存位置的对象)这就是标准没有为引用指定存储空间的原因。为了优化自由。
更新:关于您的第一个疑问,y
的{{1}}是一个完整的变量(它被声明为这样)而不是参考。因此,为其指定任何其他值都不会改变main
的值。在C ++中,当您在表达式中评估引用时,如下所示:
x
它被评估为所引用变量的值,即y
的值,即int x = 0;
int& y = x;
// Right hand side is the evaluation of the reference y
int z = y;
。 x
是一个与0
不同的变量。
关于您的第三个疑问,z
将返回引用。当函数声明为返回引用时,它返回的是引用。引用的内容是“我就是那边的另一个”。在返回值的情况下,在汇编程序级别,如果函数未内联且调用确实发生,依此类推,x
或func2
最有可能返回的内容将是指向引用变量的指针。实际上,在C ++中,对func1
的引用是通过使用func2
推导int
指针而得到的类型。将前面的示例代码与带有指针的相同代码进行比较。
int
通过引用,*
和int x = 0;
int* const y = &x;
int z = *y;
会无声地发生。
您知道,已经在语言中引入了引用以支持运算符重载,尤其是赋值运算符。
&
它不能是一个值,也不会表现得非常糟糕(通过副本传递结果)。它必须是某种指针,但它不可能。某处会有*
或// Quizz : what is the type of (b = A(123))? What if it is a 1MB object?
// What should be the type of the right-hand side of the assignment operator?
A a, b;
a = b = A(123);
,具体取决于您如何使用Standand来表示功能。 Stroustrup没有发明许多特殊类型系统的运算符重载案例,而是决定提供两种正交功能:引用,它们是语法无关的不可变指针(以及“讨论变量”的类型),以及运算符重载,它是由干净地启用的引用。
答案 1 :(得分:0)
引用是一种使两个名称别名为同一内存的方法。 以此功能为例:
void something_cpp(int &x)
{
x = 2;
}
您可以在C语言中将其视为以下内容:
void something_c(int *x)
{
*x = 2;
}
类似于在c ++中返回引用的函数:
int something[10];
int &something2_cpp(void)
{
return something[0];
}
int main(int argc, char *argv[])
{
something2_cpp() = 10;
}
在C中可以这样想:
int something[10];
int *something2_c(void)
{
return &something[0];
}
int main(int argc, char *argv[])
{
*something2_c() = 10;
}