• 初探c++11之右值引用


    很久没写了……赶紧继续上

    这里说右值,有一种解释是说位于赋值运算符左边的是左值,右边的是右值。其实,从“右值引用”这里看的话,一种更准确的定义是,不能放在运算符左边的叫做右值,其他的叫做左值。

    好,说完右值,右值引用就好理解了,也就是对于右值的引用。那么,为什么之前没有右值引用呢?是因为右值主要都是一些临时变量,对它们的引用是没有意义的,因为理论上我们没有临时变量的任何知识,它是不可用的。而c++11引入右值引用,则主要是与move语义结合使用。那么,move语义是有什么用呢?这里的move可以按照文件操作中的"copy"和"move"两种操作中的后者来理解。例如,有一个object,内部包含有有分配好的内存。如果我们要用一个函数来生成这样一个object并且将其赋值给另外一个object,例如class_t obj1  = create_obj(),那么这里create_obj()会产生一个临时变量,这个临时变量会以深拷贝的形式赋值给obj1.而这个临时变量则会被销毁,同时内部的内存被释放。很浪费的操作。而引入move语义后,这里可以是这样,create_obj()生成的临时变量内部的内存地址会传给obj1,然后这个临时变量被销毁而这部分内存不会释放。

    右值引用的声明形式:T &&,例如,int function(int&& a){}. 需要注意的是,右值引用只能引用右值,不能引用左值。也就是说,不能引用可以放在赋值运算符左边的值。所有具名的变量一定是左值。

    带有move constuctor(移动构造函数)的声明形式如下(摘自http://imcc.blogbus.com/logs/107446664.html,有修改)

    class vector 
    {
        vector(const vector&);                // 拷贝构造函数
        vector(vector&&);                    // 移动构造函数
        vector& operator= (const vector&);    // 拷贝赋值函数
        vector& operator =(vector&&);        // 移动赋值函数
    };

    关于移动构造函数,在http://blog.csdn.net/zwvista/article/details/5665566有一个很好的例子,这里不再复制粘贴了。简言之就是,在移动构造函数里面,你可以把被右值引用的那个变量的内部资源指针置空,而把当前object的指针指向它们。

    那么,move语义什么时候触发呢?

    1. 如果class_t本身拥有移动赋值函数,那么class_t obj1 = create_obj()会触发右值引用。也就是说,你把一个右值赋值给一个有移动构造函数的object.

    2.  如果class_t本身拥有移动构造函数,那么class_t obj1(create_obj())会触发右值引用。

    3. 可以使用std::move()函数。这个函数的功能是把一个左值转换成一个右值,从而触发右值引用。

    最后,一个写的比较好的关于move语义的介绍,http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html。有兴趣可以去看看。是英文的。But an rvalue reference is not, in fact, an rvalue. It's an lvalue 很有意思的一句话。

    (在最后,我真的觉得这东西主要是为了提升STL性能的……)

  • 相关阅读:
    中阶 d04.1 xml解析
    中阶 d04 xml 概念及使用
    中阶 d03.5 (正篇)完整的Dao 操作数据库
    中阶d03.4 JDBC_DAO
    中阶d03.3 JDBC_CURD_Util --- 使用 junit执行单元测试(增删改查)
    单元测试 junit
    idle中上传jar包并使用的方法
    intelij idea 和 eclipse 使用上的区别
    中阶d03.2 JDBC联合properties使用,通过读取本地配置文件为代码传递参数
    swift init 初始化
  • 原文地址:https://www.cnblogs.com/l00l/p/2478174.html
Copyright © 2020-2023  润新知