博文

目前显示的是 三月, 2026的博文

【C++】左值和右值,左值引用和右值引用

图片
左值和右值,左值引用和右值引用 1.1 三类核心值类别 lvalue(左值) 特征:有 名字 ,通常可以 取地址 、可 重复引用 。 典型例子:变量名、解引用表达式。 int x = 1 ; int & r = x ; // x 是 lvalue int * p = & x ; // &x 合法 prvalue(纯右值) 特征:纯右值,通常是临时值,不保证具有可持久身份。 典型例子:字面量、临时对象、某些按值返回。 int y = 1 + 2 ; // (1 + 2) 是 prvalue std:: string s = "hi" ; // "hi" 转换后形成临时 prvalue xvalue(将亡值)(C++ 11) 特征:将亡值,有身份,但资源可被“接管”。 典型例子: std::move(x) 的结果、某些返回右值引用的表达式(如返回T&&类型的函数)。 std:: string a = "abc" ; std:: string b = std:: move ( a ); // std::move(a) 是 xvalue 2. std::move 不移动:它只是把左值变成右值(将亡值) 这句话是理解移动语义的支点。 std::move(x) 做的是 类型转换 :把 x 转成 T&& ,令表达式呈现 xvalue 性质。 真正的移动发生在:移动构造/移动赋值被选择并执行时。 这也解释了为什么在转发场景不能乱用 move :它会把原本的 lvalue 也强行当成可被移动的来源。 3. 引用折叠:把“转发引用”变成可计算规则 3.1 折叠发生在何处 当类型推导、 typedef/using 、模板实例化等导致“引用的引用”出现时,编译器会进行引用折叠。 例如: template < class T > void f ( T && x ); // T 发生推导,可能形成引用叠加 3.2 引用折叠四条规则(必须熟练) T& & -> T& T...

【C++】类型限定符const

图片
Const的用法 const 的本质:类型系统的一部分 const 不是“运行时保护”,而是编译期的类型约束:约束“通过该名字/表达式能否修改某个对象”。 const 可以参与重载(尤其在成员函数与引用/指针参数中)  const 不提供并发同步语义(不等价于线程安全),仅代表“逻辑上的只读”,而不代表“物理上的线程安全”。 const 修饰对象:必须初始化、不可再赋值 const int a = 10;   // 必须初始化 // a = 20;          // 错误:不可修改 要点: 定义时必须初始化(除非是某些特殊存储期/延迟初始化场景,但常规写法即“必须初始化”)。 这是“对象不可赋值”的约束:并不意味着对象所在内存不可写(那是更底层的系统层语义)。 const 修饰指针/引用:顶层 const 与底层 const 这部分建议用“const 修饰的是谁”来稳定理解: 看 * 的左右: * 左边:约束“指向的对象”(底层 const) * 右边:约束“指针本身”(顶层 const int a = 10; int* const p1 = &a;        // 顶层const:p1 不可重新指向 const int* p2 = &a;        // 底层const:*p2 不可改,但 p2 可改 const int* const p3 = &a;  // 底层 + 顶层 const int& r = a;          // 引用的 const 本质是底层const:不能通过 r 改 a 顶层/底层 const 的赋值规则 顶层 const:拷贝时一般可忽略(因为拷贝的是值/指针本身)。 底层 const:是“被指向对象不可改”的约束,不能丢。 int x = 1; const int cx = 2; const int* pc = &cx; // 指向 const int int* p = &x; // p = pc;        ...