C++ 通过引用返回非频率变量和频率变量的diff btwn函数
考虑下面的代码C++ 通过引用返回非频率变量和频率变量的diff btwn函数,c++,reference,pass-by-reference,C++,Reference,Pass By Reference,考虑下面的代码 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
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";
}
代码运行得非常好,但我对下面列出的几点怀疑:
我困惑是因为我试图把C++与C联系在一起,因为一切都很清楚,但是这里主要是由于缺少对变量变量的内存布局描述,所以如果有人能告诉我,那么对
在x
,它是func1
的本地对象,其生命周期在返回时结束。然后,在main
中,指定所引用变量的内容(func1
的x
,该变量以根吃蒲公英)来初始化main
的局部变量x
。这是未定义的行为,这意味着允许程序将其解释为它想要的任何内容,格式化硬盘或其他任何内容。(很可能,func1
返回了指向被调用堆栈帧变量的指针,该变量可能仍然包含正确的值,因为当堆栈上的值将被下一次函数调用压碎时,为什么还要费事擦除这些值呢?)无论如何,程序是否会使用其他优化选项编译,它可能会给出另一个答案
在func2
中,返回的是对某物的引用。这就是x
所指的东西,它指的是main
的y
。然后,将引用变量的值分配给main
的x
,即y
关于引用的内存布局问题,在C中,指针是内存中的地址。时期无路可逃。在C++中,引用是一个更高级的机制,你可以“引用一些东西”、“谈论一些东西”、“看它就是我在那里”。strong>它们完全可以作为普通指针实现。但作为一种语言概念,它们更易于优化,因为它们是不可变的。(一旦设置了引用,它就不能被更改。它引用了一些东西——甚至是位于无效内存位置的对象)这就是标准没有指定引用存储的原因。为自由优化
更新:关于您的第一个疑问,main
的x
是一个完整的变量(声明为该变量),而不是一个引用。因此,给它分配任何其他值都不会改变y
的值。在C++中,当您在表达式中评估引用时,如:
int x = 0;
int& y = x;
// Right hand side is the evaluation of the reference y
int z = y;
它被计算为引用变量的值,即x
的值,即0
。而z
是一个不同于x
的变量
关于第三个疑问,func2
将返回一个参考。当函数声明为返回引用时,它返回的是引用。推荐信是这样写的:“我是那边的另一个”。对于返回值,在汇编器级别,如果函数没有内联并且调用确实发生等等,则func1
或func2
最有可能返回的将是指向引用变量的指针。实际上,在C++中,引用<代码> int <代码>是通过< <代码> int >代码>指针> <代码> */COD>获得的。将前面的示例代码与带有指针的相同代码进行比较
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);
它不能是一个值,否则将执行非常糟糕的操作(通过副本传递结果)。它必须是某种指针,但不可能是。在某个地方会有
&
s或*
s,这取决于您对标准和功能的描述方式。Stroustrup没有发明许多特殊类型系统中的运算符重载,而是决定提供两种正交功能:引用,这是无语法麻烦的不可变指针(和“谈论变量”的类型),以及通过引用完全启用的运算符重载。在func1
中,您返回的是对某事物的引用。这是x
,它是func1
的本地对象,其生命周期在返回时结束。然后,在main
中,指定所引用变量的内容(func1
的x
,该变量以根吃蒲公英)来初始化main
的局部变量x
。这是未定义的行为,这意味着允许程序将其解释为它想要的任何内容,格式化硬盘或其他任何内容。(最有可能的是,func1
返回被调用堆栈帧变量的指针,该变量可能仍然包含正确的值,因为当堆栈上的值将被下一次函数调用压碎时,为什么还要费事擦除这些值呢?)
// 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);
void something_cpp(int &x)
{
x = 2;
}
void something_c(int *x)
{
*x = 2;
}
int something[10];
int &something2_cpp(void)
{
return something[0];
}
int main(int argc, char *argv[])
{
something2_cpp() = 10;
}
int something[10];
int *something2_c(void)
{
return &something[0];
}
int main(int argc, char *argv[])
{
*something2_c() = 10;
}