use*_*748 2 c++ reference function
我有两段代码:
int f1(int b)
{
return b;
}
int & f2(int b)
{
return b;
}
Run Code Online (Sandbox Code Playgroud)
这些功能有什么区别?我知道第二个返回一个引用,但由于我可以以相同的方式使用这两个函数,有什么区别?
编辑:这个功能更好吗?
int && f2(int b)
{
return b;
}
Run Code Online (Sandbox Code Playgroud)
什么时候应该使用返回引用的函数?
Edit2:那我什么时候应该使用返回Rvalue引用的函数?
int f1(int b) {
return b;
}
Run Code Online (Sandbox Code Playgroud)
返回整数b.
int & f2(int b) {
return b;
}
Run Code Online (Sandbox Code Playgroud)
返回对函数返回时销毁的整数b的引用.换句话说,您通过值将b传递给函数,这意味着b在函数的堆栈框架中有一个地址.函数返回后,该函数的堆栈帧中的任何内容(包括您返回引用的b)都不再存在.所以,你不知道引用实际引用了什么,所以你不能使用它.
编辑:您编辑的功能并不是更好.这样会更正确:
int& f2(int& b) {
return b;
}
Run Code Online (Sandbox Code Playgroud)
除非您遇到类似@ user4581301给出的示例,否则您应该永远不会返回对您要返回的函数内创建的对象的引用,原因如上所述!
如果要将对象传递给函数,并让函数对该对象执行某些操作而不复制该对象,请执行以下操作:
void f2(int& b) {
... do stuff to b
}
Run Code Online (Sandbox Code Playgroud)
考虑一个包装数组的简单类,仅仅是为了提供一个OP可以对返回的引用做什么的示例.
class example
{
private:
int array[]= {1,2,3,4,5,6,7,8,9,0};
public:
int get(int index)
{
return array[index];
}
int & get2(int index)
{
return array[index];
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们有一个例子,它不会进入未定义行为的荒地,并且可以向您展示这种全副武装的操作参考的力量.
说我们有
example x;
Run Code Online (Sandbox Code Playgroud)
我们可以调用get函数来检索值
int val1 = x.get(1);
int val2 = x.get2(2)
Run Code Online (Sandbox Code Playgroud)
但我们也可以
x.get2(3) = 30;
Run Code Online (Sandbox Code Playgroud)
因为get2返回一个我们可以分配给它的引用并使赋值保持不变.
如果要在示例中添加索引运算符,这是非常有用的
int & operator[](int index)
{
return array[index];
}
Run Code Online (Sandbox Code Playgroud)
因为它允许预期的数组行为
int val = x[5];
x[6] = 10;
Run Code Online (Sandbox Code Playgroud)
Tony D带来了另一个重要特征.返回引用通过引用返回.除了允许修改返回的对象之外,这不会复制并节省通过制作副本所消耗的任何努力.对于整数的示例情况,这是没有实际意义的.传递整数和引用整数的成本要么相同要么接近,以至于无关紧要.对于可能需要花费大量精力来复制的更大,更复杂的对象或者不能或不应该复制的对象,情况并非如此.
BigFreakingObject & getBigFreakingObject();
Run Code Online (Sandbox Code Playgroud)
将允许呼叫者在a上运行BigFreakingObject
而不会产生重复它的成本.然而,这将把钥匙交给王国,并允许来电者做BigFreakingObject
任何BigFreakingObject
允许的权限,这可能与BigFreakingObject
所有者的要求相冲突.
声明引用作为const
与
const BigFreakingObject & getBigFreakingObject();
Run Code Online (Sandbox Code Playgroud)
要么
BigFreakingObject const & getBigFreakingObject();
Run Code Online (Sandbox Code Playgroud)
将提供BigFreakingObject
但不允许呼叫者修改其状态的参考,保护所有者BigFreakingObject
免受任何不愉快的意外.
有关详细信息,请阅读Const Correctness.