0%

从【移动构造】的意义,来学习值类别、值类型、生命周期、表达式类型

2020年3月16日 下午6:00

补充:

  1. 什么是右值引用,跟左值又有什么区别?
    1. 右值引用是C++11中引入的新特性 , 它实现了转移语义和精确传递。它的主要目的有两个方面:
    2. 消除两个对象交互时不必要的对象拷贝,节省运算存储资源,提高效率。
    3. 能够更简洁明确地定义泛型函数。
  2. 左值和右值的概念
    • 左值:能对表达式取地址、或具名对象/变量。一般指表达式结束后依然存在的持久对象。
    • 右值:不能对表达式取地址,或匿名对象。一般指表达式结束就不再存在的临时对象。
  3. 右值引用和左值引用的区别:
    1. 左值可以寻址,而右值不可以。
    2. 左值可以被赋值,右值不可以被赋值,可以用来给左值赋值。
    3. 左值可变,右值不可变(仅对基础类型适用,用户自定义类型右值引用可以通过成员函数改变)。

小总结:

  1. 我认为左值和右值,就是C++设计者给数据、对象设计的一个标签。
  2. 你作为程序员,你可以将一个数据、对象打上合适的标签,甚至可以给他们更换标签,但是这个过程对于内存上真实存在的数据来说,其实是无感的,他依然存在内存中的原有位置,一动不动。
  3. 当数据、对象有了这个标签属性之后,在加上C++内在的对不同标签的数据处理机制(其实就是一个if-else),来区分对象移动、对象拷贝。
  4. C++设计者是为了给C++添加对象移动这一新功能,而设计了这组新的数据标签

注:为了节约时间,我仅仅将重要的理解方法记录在这里,具体的知识点的讲解,还是去看原文。

宏观角度理解

  • 宏观的一句话总结:值类别、值类型、生命周期、表达式类型、移动构造等等知识点,其实就是从效率的角度进行思考,思考如何在完成相同功能的前提下,能够从逻辑上使用更少的对象、更少的步骤,从实际上如何更少的使用内存空间。
  • 我觉得这不仅仅是学习移动构造系列知识的角度,学习任何关于编程的知识都要站在这个角度进行思考。这样你才能理解的舒服,弄懂背后的逻辑。最后达到不死记知识点,而是靠理解来进行记忆(耗叔的话)。

具体的理解

  1. 拷贝构造就会生成临时对象,造成新的开销,那么我们的目的就是减少拷贝构造的次数,减少临时对象的数量。
  2. 解决方法最重要的有一条就是:用移动构造,替换掉拷贝构造
  3. 对于 smart_ptr,我们使用右值引用的目的是实现移动,而实现移动的意义是减少运行的开销,其实就是生成临时对象的开销。这里的移动指的是移动构造,移动构造和拷贝构造是。

几个零散的知识点:

  1. “值类别”(value category)和“值类型”(value type)
    • 是两个看似相似、却毫不相干的术语。
    • 前者指的是上面这些左值、右值相关的概念,
    • 后者则是与引用类型(reference type)相对而言,表明一个变量是代表实际数值,还是引用另外一个数值。
    • 在 C++ 里,所有的原生类型、枚举、结构、联合、类都代表值类型,只有引用(&)和指针(*)才是引用类型。
    • 在 Java 里,数字等原生类型是值类型,类则属于引用类型。在 Python 里,一切类型都是引用类型
  2. 临时对象的生命周期:
    • C++ 的规则是:一个临时对象会在包含这个临时对象的完整表达式估值完成后、按生成顺序的逆序被销毁,除非有生命周期延长发生
    • 注意:这里说的是临时对象
  3. 为了方便对临时对象的使用,C++ 对临时对象有特殊的生命周期延长规则
    • 如果一个 prvalue 被绑定到一个引用上,它的生命周期则会延长到跟这个引用变量一样长