C++初始化
发表于|更新于|笔记
1. 列表初始化
初始化列表用{}表示,正常是没有类型的,但是在函数的参数列表中可以用std::initializer_list表示能够接收初始化列表。
std::initializer_list在一下情况会自动构造对象:
- 用于列表初始化对象,并且构造函数需要能够接受std::initializer_list参数
- 用于赋值或者函数调用,并且赋值运算符/函数需要能够接受std::initializer_list参数
- 绑定到auto或者包括在范围 for 循环中
auto p = { 1,2,3 };//能够推导出类型为std::initializer_lis
auto p2 { 1,2,3 };//无法推导
文章作者: 沉迷修仙の雯欂
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 雯欂の修仙笔记!
相关推荐
2025-11-30
C++代码书写规范
变量命名使用下划线命名法,函数命名使用大驼峰命名法,类和结构体使用大驼峰命名法,文件名使用下划线命名法 全局变量和常量使用k+大驼峰命名法,类成员变量可以以下划线作为结尾,结构体成员变量不加下划线 命名空间用下划线命名法 尽量不要使用全局变量,可以将其封装进对象里 ros中回调函数的形参可以使用const name & 修饰 函数声明中const修饰符无意义,只需在函数定义中使用 模板类的静态成员变量是每个特定实例化类型共享一份,而不是所有实例化类共享同一份。例如MyClass<int>和MyClass<double>的静态成员变量是独立的。
2025-11-30
C++引用
1. 左值与右值 1.1 左值 左值是可以取地址的对象,比如变量名和解引用的指针变量。 // 以下的a、p、*p、b都是左值 int a = 3; int* p = &a; *p; const int b = 2; 1.2 右值 右值是不能取地址的对象,比如常量、临时变量、函数返回值、运算符返回值等。 double x = 1.3, y = 3.8; // 以下几个都是常见的右值 10; // 字面常量 x + y; // 表达式返回值 fmin(x, y); // 传值返回函数的返回值 2. 左值引用与右值引用 无论左值引用还是右值引用,都是给对象取别名。 2.1 左值引用 是指对左值的引用,作用是避免对象拷贝。 int& ra = a; 2.2 右值引用 是指对右值的引用,作用是延长对象的生命周期。 int&& rr = 10; 2.3 对比与总结 左值引用可以指向左值,在指向右值时需要const修饰 右值引用可以指向右值,在指向左值时需要std::move() cons...
2025-11-30
C++踩坑记录
1. 数组智能指针 在创建指向数组的智能指针时需要注意传入模板的类型需要加中括号,例如创建八个元素的整数数组指针std::unique_ptr<int[]> ptr = std::make_unique<int[]>(8) 2. 移位操作 移位运算符即按二进制形式把所有数字向左移动相应的位数,高位舍弃,空位补0。因此移位后返回的字符宽度与需要移位的数字字符宽度保持一致 注意移动的位数不得超过变量的字符宽度,不然会导致未定义行为 此时便出现了易错点:移位操作时存在整数提升现象,即小于或等于int的整数类型在运算时会被自动提升为int或unsigned int(当int不够存储原类型数据),这样是不安全的,因此需要在移位前先显示进行类型转换 参考文章C++ 整数提升与移位陷阱 参考文章C++移位运算符详解 3. 判断两个double类型是否相等 由于浮点数储存的精度问题,直接使用相等运算符(==)判断两个double类型的数是否相等可能会导致意外的结果,因此可以设置一个极小的阈值作为两数相差的上限 bool isEqual(double a, double ...
2025-11-30
STL容器
1. Array 1.1 初始化 std::array无构造函数,只含有非静态公共成员变量,所以属于聚合类型,其他聚合类型还有数组类型。 对聚合体使用列表初始化被称为聚合初始化,它也是列表初始化的一种形式,聚合体初始化需要层层嵌套。 std::array的定义大概如下: template<typename T, std::size_t N> class array { public: T _data[N]; }; 它的聚合初始化如下: /** * 第一层是为了初始化std::array本身 * 第二层是为了初始化里面的数组 */ std::array<int, 3> arr{{1,2,3}}; 由于 C++ 聚合初始化时允许省略所有的内部花括号,所以可以简写做: std::array<int, 3> arr{1,2,3}; 对于二维数组。标准形式的初始化如下: /** * 最外两层是为了初始化外层array * 内部两层是为了初始化内层array */ std::array<...
2026-01-26
多线程通信和同步
2. 锁 2.1 互斥锁mutex 成员方法: lock()获取锁资源,如果获取不到则阻塞等待 unlock()释放锁资源 try_lock()尝试获取锁资源,如果获取成功返回true;否则返回false,并不会阻塞线程 互斥锁的坑: 释放锁资源只是告诉操作系统要释放锁资源,故而并不是立即释放,此时如果再次立即获取锁资源,此线程会再次上锁,其他线程无法获取 2.2 超时锁timed_mutex 成员方法: try_lock_for(std::chrono::duration)在指定的时间期限内尝试获取互斥锁。如果在这个时间期限内获得了锁,函数返回 true;否则函数返回false。如果接受的参数接近0,那么函数的功能基本就等于try_lock() 2.3 递归锁recursive_mutex和recursive_timed_mutex 特点: 可以多次lock()和unlock()当计数为0时才真正释放,而普通锁多次上锁属于未定义行为 2.4 共享锁shared_timed_mutex(C++14)和shared_mutex(C++17) 成员方法: ...
2026-01-29
Chapter 3 锁资源管理和条件变量
1. RAII锁管理类 借助对象实现构造时可自动加锁,析构时自动解锁,并通过{ }控制锁的临界区 1.1 互斥锁管理类lock_guard(C++11) 关键词标记: adopt_lock标记/adopt_lock_t标记(C++11),用于手动加锁后,想让RAII工具接管解锁的场景,此时不需要再次手动释放锁 1.2 互斥锁管理类unique_lock(C++11) 关键词标记: adopt_lock标记/adopt_lock_t标记(C++11) defer_lock延后拥有,只有再次手动上锁后才拥有锁,如果未拥有锁,则出栈区不释放。当unique_lock作为成员变量时需要使用此标记 try_to_lock尝试获取锁,不阻塞,获取失败退出栈区不释放 特点: 可以调用unlock()和lock()来临时解锁和上锁 可以调用owns_lock()来判断是否拥有锁,拥有则返回true 比lock_guard更加灵活,但是效率、内存占用差一些,同时支持移动构造 1.3 共享锁管理类shared_lock(C++14) 特点: ...