文章目录
1.引用
1、变量是内存的命名,而引用是变量的别名,二者指向同一内存地址。引用不是变量,无独立地址空间。
2、必须在定义时初始化,后续无法绑定到其他对象。
语法:类型& 引用名 = 目标变量
1.引用分类
1.左值引用
- 常规引用(左值引用):绑定左值(有内存地址、可寻址的变量)。
- 常量左值引用(const T&):可绑定左值或右值(临时值),常用于函数参数避免拷贝。
当const T&绑定右值时,编译器创建的临时变量具有以下特点:
- 类型为const T(权限收缩,避免通过引用修改临时变量);
- 存储右值数据,生命周期与引用绑定周期一致。
函数返回值的销毁涉及三个关键阶段:
1.返回值构造:函数执行return语句时创建返回对象
2.临时对象传递:返回值从函数栈帧传递到调用者
3.销毁触发:临时对象在表达式结束或赋值完成后析构
2.右值引用
绑定右值(临时值、表达式结果),用于移动语义和完美转发。不延长生命周期。
语法:类型&& 引用名 = 右值
1.std::move
std::move 是 C++11 引入的一个标准库函数,用于将左值强制转换为右值引用(T&&),从而触发移动语义。其本质是一个类型转换工具,并不实际移动任何数据。
2.右值引用的核心用途:移动语义
转移资源所有权,避免深拷贝
- 移动构造函数
- 移动赋值运算符
3.完美转发
一种将参数从一个函数或对象无损失地传递给另一个函数或对象的技术。其核心目标是保持原始参数的所有属性,包括值类别(左值或右值)和常量性,从而避免不必要的复制或移动操作。
1、const 左值会被转发为 const 左值引用,const 右值会被转发为 const 右值引用。
2、在参数传递时,若不使用完美转发,右值可能被意外转换为左值,导致额外的复制或移动操作。
无论变量的类型是左值引用(T&)还是右值引用(T&&),命名变量本身永远是左值。
使用std::forward。
在 C++ 中,完美转发主要通过 引用折叠(Reference Collapsing)和 转发引用(Forwarding Reference,又称万能引用)结合 std::forward 实现。
1.转发引用:
- 1.T&& 是转发引用,可绑定到左值或右值
- 2.如果实参是左值,T被推导为Type&。
- 3.如果实参是右值,T被推导为Type。
2.引用折叠规则:
- 1.& & 折叠为 &
- 2.& && 折叠为 &
- 3.&& & 折叠为 &
- 4.&& && 折叠为 &&
3.std::forward:根据T的推导结果,确保参数以原始值类别传递。
template<typename T>
T&& forward(std::remove_reference_t<T>& arg) noexcept;
template<typename T>
T&& forward(std::remove_reference_t<T>&& arg) noexcept;
1.当 T 是 Type&(左值)时,返回 Type&。
2.当 T 是 Type(右值)时,返回 Type&&。
高级应用
1、emplace_back() 通过完美转发参数,直接在容器内构造对象,进一步提升性能。
2、自定义类变量移动构造函数必须声明为 noexcept,否则vector扩容时使用拷贝构造。
2.指针
指针的本质 —— 内存地址
核心概念
1.内存地址:每个变量在内存中都有一个唯一的地址,类似于房间号。
2.指针变量:专门用于存储其他变量地址的变量。
3.解引用操作:通过指针访问其指向的对象。
语法基础
& 取地址运算符,获取变量地址
- 解引用运算符,访问指针指向的值
3.Const
顶层const表示指针本身是个常量,底层const表示指针所指向的对象是个常量。
看const位置,确定叫什么 const和位置
指向常量的指针 const int p; 不可通过p修改值
指针常量 int const p = &x; 指针本身不可修改
4.Auto
核心定义
1、类型推导:编译器根据初始化表达式自动推断 auto 变量的类型。
2、替代显式类型:避免编写冗长的类型名称,尤其是复杂的模板类型。
常见用法
1、当引用作为初始值时,真正参与的是引用对象的值。
2、会忽略顶层const但保留底层const.
3、可以结合使用,使用auto时用const和&等。
5.decltype
核心概念:编译期类型推导
decltype 的作用是在编译期分析表达式的类型,而不计算表达式的值。其基本语法为:
decltype(expression) var; // 声明var的类型为expression的类型
6.结构体
核心定义
1、结构体:是一种用户自定义的数据类型,可将不同类型的数据组合成一个逻辑单元。
2、成员变量:构成结构体的数据元素。
3、访问方式:通过点运算符(.)访问成员。
结构体对齐的核心规则:
1.成员对齐:每个成员的起始地址是其类型大小的倍数。
2.结构体总大小:是最大成员类型大小的倍数。
3.嵌套结构体:成员起始地址是嵌套结构体最大成员的倍数。
指有效对齐数。
自身对齐值:由数据类型决定(如int为 4 字节,double为 8 字节)。
指定对齐值:通过#pragma pack或alignas指定。
有效对齐值:取自身对齐值和指定对齐值中的较小值。
7.共用体
核心定义
共用体:一种特殊的数据类型,所有成员共享同一块内存空间。
内存占用:共用体的大小由其最大成员决定。
成员访问:同一时间只能使用一个成员(修改一个成员会覆盖其他成员的值)。
1.大小端
大端序(Big Endian)
高位字节在前:数据的最高有效字节(MSB, Most Significant Byte)存储在最低地址,最低有效字节(LSB)存储在最高地址。
小端序(Little Endian)
低位字节在前:数据的最低有效字节(LSB)存储在最低地址,最高有效字节(MSB)存储在最高地址。
类比:类似计算机内部处理数据的方式(从低位到高位计算)。
网络协议(如 TCP/IP)通常使用大端序(网络字节序)
8.枚举
一种用户定义的类型,由一组命名的整数常量组成。
枚举成员:枚举中定义的常量,默认从 0 开始递增。
作用域:枚举成员的作用域取决于枚举的类型(传统枚举或强类型枚举)。
传统枚举:由编译器决定(通常是int)。
强类型枚举:默认是int,可显式指定。
赋值时,需要赋枚举里面的值,不能直接1,2