东莞网站设计的公司,王烨江婉柔,谷歌广告联盟网站,谷歌网站推广费用引用是一个变量#xff0c;它引用其他变量的内存位置
int x 34;
int lRef x;
标识符 IRef 就是一个引用。在声明中#xff0c;引用是通过 来指示的#xff0c;出现在类型与变量的标识符之间#xff0c;这种类型的引用称为左值引用左值看作是一个关联了名称的…引用是一个变量它引用其他变量的内存位置
int x 34;
int lRef x;
标识符 IRef 就是一个引用。在声明中引用是通过 来指示的出现在类型与变量的标识符之间这种类型的引用称为左值引用左值看作是一个关联了名称的内存位置允许程序的其他部分来访问它 名称 解释为任何可用于访问内存位置的表达式右值则是一个临时值它不能被程序的其他部分访问
int square(int a)
{return a * a;
}
int main()
{int x 0; // 1x 12; // 2cout x endl; // 3x square(5); // 4cout x endl; // 5return 0;
}
x 是一个左值这是因为 x 代表一个内存位置它可以被程序的其他部分访问例如上面注释的第 2、3、4 和 5 行表达式 square(5) 却是一个右值因为它代表了一个由编译器创建的临时内存位置以保存由函数返回的值。该内存位置仅被访问一次也就是在第 4 行赋值语句的右侧。在此之后它就会立即被删除再也不能被访问了。对于包含右值的内存位置来说其本质就是它虽然没有名称但是可以从程序的其他部分访问到它C11 引入了右值引用的概念以表示一个本应没有名称的临时对象。右值引用的声明与左值引用类似但是它使用的是 2 个 符号)
int rRef square(5);
cout rRef endl;
声明一个右值引用给一个临时内存位置分配一个名称这使得程序的其他部分访问该内存位置成为了可能并且可以将这个临时位置变成一个左值。右值引用不能约束到左值上所以以下代码将无法编译
int x 0;
int rRefX x;
初始化完成之后这个包含值 square(5) 的内存位置有了一个名称即 rRef1所以 rRef1 本身变成了一个左值。这意味着后面的这个初始化语句将不会编译int rRef2 rRef1;究其原因就是右侧的 rRef1 不再是一个右值。综上所述临时对象最多可以有一个左值引用指向它。如果函数有一个临时对象的左值引用则可以确认程序的其他部分都不能访问相同的对象
int rRef1 square(5);
右值一般是不可寻址的常量或在表达式求值过程中创建的无名临时对象短暂性的。左值是可寻址的变量有持久性左值和右值主要的区别之一是左值可以被修改而右值不能。左值引用引用一个对象右值引用就是必须绑定到右值的引用C11中右值引用可以实现“移动语义”通过 获得右值引用。 右值引用和相关的移动语义是C11标准中引入的最强大的特性之一通过std::move()可以避免无谓的复制提高程序性能。
特殊情况
但const左值引用除外由于const的不可变性所以const引用可以指向右值我们经常使用const引用作为函数参数传递 const int e a*3; // 正确左值引用const引用可以绑定到一个右值上
例子
int x 6; // x是左值6是右值
int y x; // 左值引用y引用xint z1 x * 6; // 错误x*6是一个右值
const int z2 x * 6; // 正确可以将一个const引用绑定到一个右值int z3 x * 6; // 正确右值引用
int z4 x; // 错误x是一个左值
参考链接
C左值和右值详解版一篇文章弄懂C左值引用和右值引用 - html中文网