c11右值引用--笔记

C11中有左值引用和右值引用

左值引用

对一个变量的别名,不会调用拷贝构造,对别名的操作影响原值

eg:

 

运行结果:

 

右值引用

对匿名变量的引用,提出右值引用的原因:充分利用在函数调用过程中产生的临时变量,对这个临时变量达到最大限度的使用率

常用的匿名变量(对象):

fun(A a());           //此时生产了一个临时变量,且无名,这就是右值

int  add(int a, int b)

{

       return (a + b);   //此时的(a+b)的结果就是一个临时变量,且无名,这就是右值

}

右值引用如何使用

并不是变量自动就会变成右值引用,需要用户按右值引用的方式定义接口、定义变量,才会触发右值引用,举个例子:

1)

 fun (A a) { //再怎么传也不会变成右值引用

//TODO

}

如果用户使用  fun(A()); //则就是调用一个普通的函数

2)

如果想使用右值引用就需要用户按右值引用定义接口,才会调用到这个右值引用

fun(A&& a){

//TODO

}

fun(A());   //这时编译器发现你有定义相关接口,就会去调用右值引用的函数了

记住: 右值引用可以优化过程中产生的临时变量,但并不代表你什么都不做它就能优化,如果你想优化,需要你手动实现相关接口才行;  右值引用只是一个功能,你可以选择用或不用。

上面1)和2)说的都是调用函数中的形参问题,下面说说变量问题;

int a=2, b=3;

int     c = add(a, b);         //c就是再普通不过的一个左值,add先产生一个临时变量然//后再将临时变量赋值给c

int&&  d = add(a, b);         //d就是一个右值,add过程中产生一个临时变量,d就是这//个临时变量的一个“引用”,加引号是因为说d是一个偷盗//者更合适,它把那个临时变量给偷过来了

注意:此处使用int并不是很明显,如果使用一个T,T中包含指针数组,大家可能更容易明白

上面的c和d是程序员用户自己写的,他不在乎过程中多一次拷贝就按c的方式写;如果他是一个处女座的程序员,他可能更喜欢使用d的方式;再次重申:右值引用是一功能选项,你可以选择用与不用。

扩展一

上面说的都是最正常的情况,即只对匿名变量(对象)使用右值引用,但是我们总是喜欢知道了一个规则后,就千方百计利用这个规则,比如下面这种使用场景:

void test(){

T t;

fun(std::move(t));       //将t转换成了一个右值引用,如果T中包含指针,此行后t中的指//针就变成了nullptr

                                       //当然前提是fun有右值引用接口的声明和实现

}

void fun(T& t);    //左值引用

void fun(T&& t);  //右值引用

举一个可能用到的场景:

void print_(std::string  str) {

       std::cout<<str<<”\n”;

}

void print_(std::string&& str) {

       std::cout<<str<<”\n”;

}

void test() {

       std::string str(“Hello World!”);

       print_(str);                      //产生一次拷贝,生成临时变量

       print_(std::move(str));          //右值引用 ,调用移动拷贝

}

 

  

猜你喜欢

转载自www.cnblogs.com/guoliushui/p/9520175.html