Aquacolor

Aquacolor



新坑

Gumdrop · 2025-08-20 · 14浏览 · 未分类


(一直感觉c++比其他见过的语言走的进化线路离谱好多,可能是因为保留了内存管理和强类型)

  1. 左值和右值 (不讨论指针类型,因为现代c++有意减少指针类型) 可以形象认为:

    1. 左值有名,右值无名

    2. 左值可以在等号左或右,右值只能在等号右

    3. 右值可以认为是临时的,其生命周期、作用域都小

    可以把左值认为包含:

    1. 学编程的时候最开始学的变量,有名字的那种

    2. 左值引用、常引用

    可以认为右值包含:

    1. 字面量

    2. 表达式、函数调用

    (这里还不涉及现代c++不要给自己加难度) (在学习语言的时候经常将等号左/右的量叫做左/右值,这种称呼是强调通俗易懂,在交流中方便指明中心对象,而非其具有这节的左/右值的特性。把它们叫做等号左/右值)

  2. 赋值运算符=和函数调用() 一个足够不严谨的说法可以管用: 函数调用对每个参数进行赋值,或赋值运算进行了将等号右值传参到等号左值类型的步骤。 所以认为两者等价。

  3. 绑定、拷贝和移动 (这里用=的方式说明,但其实这一类语法法通常在传参和返回值时使用)

    1. 绑定 绑定的左边一定是一个引用类型,并且效率最高。它们通常的语义有很大不同。

      //别名,完全访问权限,为域外的持久变量创建一个在域内的引用以扩展作用域……
      T& lref = lvalue;
      T& lref = lref;
      
      //别名,持久变量的生命周期将被结束、延长临时变量生命周期……
      T&& rref = rvalue;
      T&& rref = rref;
      
      //在禁止可能改变值的操作的前提下扩展作用域……
      const T& clref = lvalue;
      const T& clref = lref;
      const T& clref = rvalue
      

      做一些解释:

      1. 扩展作用域,即传参到函数体作用域内。

      2. 右值引用的“将要结束”指的是一个持久变量被std::move()至一个右值引用时,两个变量都还能使用。真正结束持久变量生命周期是在右值引用进行了移动时。(std::move()以后会提,这里布局不好只能循环依赖了)(这里的生命周期结束其实只是被初始化了,但是如果它在被再次构造前就被使用,将会引发警告;所以使用同一个词表示)

      3. 延长临时变量生命周期是所有引用都具有的特性,为一个临时变量创建引用会延长临时变量的生命周期与引用一致。

      4. 这告诉我们所有引用类型都是等号左值,即使是右值引用

    2. 拷贝和移动 (这里只讨论深拷贝,忽略掉那个浅拷贝的不伦不类的东西,且良好的编程习惯应该默认为类编写深拷贝的拷贝构造和拷贝赋值) 拷贝发生在左值向非引用类型赋值时;移动发生在右值向非引用类型赋值时。

      //复制就是复制
      T var = lvalue
      T var = lref
      
      //移动也可能是复制、正式结束引用对象的生命
      T var = rvalue
      T var = rref
      

      一些解释:

      1. 注意到右值引用也是别名,所以对右值引用的操作在效果上应该和直接对被引值的操作一致,于是下面三个语句等价:

        //T rvalue;
        //T&& rref = std::move(rvalue);
        T var = rref;
        T var = std::move(rref);
        T var = std::move(rvalue);
        
      2. 正式结束生命,即所有权从临时变量或一个持久变量转移到另一个持久变量。

      3. 由于常量右值引用按语义不能进行移动操作,这会改变被引值,所以常量右值引用不需要被使用,常引用就是常量左值引用。

      4. 拷贝构造/赋值函数参数是const MyClass&,移动构造/赋值函数参数是MyClass&&。如果要强调移动,则在移动所使用的函数加noexcept

  4. 模板 构造函数、赋值函数通常会写移动、拷贝两个语义的版本,但其他功能函数有更新的模板函数写法。

    (这里列出可能的写法进行对比以加深理解)

    //template<typename Arg>
    T func(Arg);//全拷贝,最简单但性能差且不现代
    T func(Arg&);//仅支持左值
    T func(const Arg&);//全支持,但const
    T func(Arg&&);//万能转发机制,可以做到非const
    

    (后面的内容需要补充一些c++模板编程的知识,目前决定是使用c++17标准,因为20见的少)



©

comment 评论区

添加新评论

face表情



  • ©2026 bilibili.com

textsms
内容不能为空
昵称不能为空
email
邮件地址格式错误
web
beach_access
验证码不能为空
keyboard发表评论


star_outline 咱快来抢个沙发吧!




©2026 Aquacolor

Theme Romanticism2.2 by Akashi
Powered by Typecho