当前位置:嗨网首页>书籍在线阅读

11-右值引用

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

18.1.9 右值引用

传统的C++引用(现在称为左值引用)使得标识符关联到左值。左值是一个表示数据的表达式(如变量名或解除引用的指针),程序可获取其地址。最初,左值可出现在赋值语句的左边,但修饰符const的出现使得可以声明这样的标识符,即不能给它赋值,但可获取其地址:

int n;
int * pt = new int;
const int b = 101;   // can't assign to b, but &b is valid
int & rn = n;        // n identifies datum at address &n
int & rt = *pt;      // *pt identifies datum at address pt
const int & rb = b;  // b identifies const datum at address &b

C++11新增了右值引用(这在第8章讨论过),这是使用&&表示的。右值引用可关联到右值,即可出现在赋值表达式右边,但不能对其应用地址运算符的值。右值包括字面常量(C-风格字符串除外,它表示地址)、诸如x + y等表达式以及返回值的函数(条件是该函数返回的不是引用):

int x = 10;
int y = 23;
int && r1 = 13;
int && r2 = x + y;
double && r3 = std::sqrt(2.0);

注意,r2关联到的是当时计算x + y得到的结果。也就是说,r2关联到的是33,即使以后修改了x或y,也不会影响到r2。

有趣的是,将右值关联到右值引用导致该右值被存储到特定的位置,且可以获取该位置的地址。也就是说,虽然不能将运算符&用于13,但可将其用于r1。通过将数据与特定的地址关联,使得可以通过右值引用来访问该数据。

程序清单18.1是一个简短的示例,演示了上述有关右值引用的要点。

程序清单18.1 rvref.cpp

// rvref.cpp -- simple uses of rvalue references
#include <iostream>
inline double f(double tf) {return 5.0*(tf-32.0)/9.0;};
int main()
{
    using namespace std;
    double tc = 21.5;
    double && rd1 = 7.07;
    double && rd2 = 1.8 * tc + 32.0;
    double && rd3 = f(rd2);
    cout << " tc value and address: " << tc <<", " << &tc << endl;
    cout << "rd1 value and address: " << rd1 <<", " << &rd1 << endl;
    cout << "rd2 value and address: " << rd2 <<", " << &rd2 << endl;
    cout << "rd3 value and address: " << rd3 <<", " << &rd3 << endl;
    cin.get();
    return 0;
}

该程序的输出如下:

 tc value and address: 21.5, 002FF744
rd1 value and address: 7.07, 002FF728
rd2 value and address: 70.7, 002FF70C
rd3 value and address: 21.5, 002FF6F0

引入右值引用的主要目的之一是实现移动语义,这是本章将讨论的下一个主题。