C++ 右值引用与一级指针

乎语百科 283 0

右值引用用于一级指针,在初始化时等号右边必须为右值,有以下几种用法:

//方式一:引用一级指针,常规用法
int a = 5;
int * &&rrpa = &a;       //右值:例子一
int * getPx() { return new int; }
int * &&rrpa = getPx();  //右值:例子二
int * pa = &a;
int * &&rrpa = std::move(pa);//右值:例子三

//方式二:引用指向常量的一级指针,以下几种为等效表示
int a = 5;
const int * &&rrpac = &a; //方式一
int const * &&rrpac = &a; //方式二

//方式三:引用一级指针的常引用,引用自身为常量
int a = 5;
int * const &&crrpa = &a;

//方式四:引用指向常量的一级指针,且引用自身为常量,以下几种为等效表示
int a = 5;
const int * const &&crrpac = &a; //方式一
int const * const &&crrpac = &a; //方式二

Microsoft Visual Studio 中连续多个 const 会被编译器解释成一个,即 const const const const int *&&const int *&& 等效,除此之外,const int const *&&Microsoft Visual Studio 中也与 const int *&& 等效,而 int *&& constQT minGW 中将会报错,在 Microsoft Visual Studio 中与 int *&& 等效。

各类型引用可修改属性如下表所示:

引用类型 修改 *rrp 修改 rrp
int * &&rrp 可以 可以
const int * &&rrp 不可以 可以
int * const &&rrp 可以 不可以
const int * const &&rrp 不可以 不可以

若将变量的地址赋予引用(例如 rrp=&x),各类型引用可接受的变量地址如下表所示:

引用类型 int变量地址 const int变量地址
int * &&rrp 可以 不可以
const int * &&rrp 可以 可以
int * const &&rrp 声明时可以 不可以
const int * const &&rrp 声明时可以 声明时可以

若将函数返回的一级指针值赋予引用(例如 rrp=getPx()),或者使用形如 rrp=(const int *) &x 的强制类型转换,此时各类型引用可接受的类型如下表所示:

引用类型 int * const int * int * const const int * const
int * &&rrp 可以 不可以 可以 不可以
const int * &&rrp 可以 可以 可以 可以
int * const &&rrp 声明时可以 不可以 声明时可以 不可以
const int * const &&rrp 声明时可以 声明时可以 声明时可以 声明时可以

由于右值引用变量自身为左值,因此不能直接将右值引用变量的值赋予另一个右值引用变量,但可以将函数返回的右值引用值赋予另一个右值引用变量(例如 rrp=getRRPx()),也可以使用 std::move() 将左值转换为右值(例如 rrp=std::move(px)),此时各类型引用可接受的类型如下表所示。比较上下两表可知,它们的差别主要在于最后两列,这是因为 int * constconst int * const 中右边的 const 修饰的是一级指针自身,而 int * const &&const int * const && 中右边的 const 修饰的是右值引用自身,代表的含义不同。

引用类型 int * && const int * && int * const && const int * const &&
int * &&rrp 可以 不可以 不可以 不可以
const int * &&rrp 可以 可以 不可以 不可以
int * const &&rrp 声明时可以 不可以 声明时可以 不可以
const int * const &&rrp 声明时可以 声明时可以 声明时可以 声明时可以

右值引用在声明时是否会创建临时变量,这与具体应用场景有关,可在编译后查看对应的汇编代码,也可参考本人另一篇博客 C++ 右值引用与 const 关键字。关于左值引用与一级指针,可参考本人另一篇博客 C++ 左值引用与一级指针

标签: # c++

留言评论

  • 这篇文章还没有收到评论,赶紧来抢沙发吧~