在学习c++的过程中时不时冒出一些概念和常用语,但是却苦于不得其解,这里整理一下.主要来源是cppreference.
目前是C++的八股
三/五/零原则
三原则
如果某个类需要用户定义的析构函数、用户定义的复制构造函数或用户定义的复制赋值运算符,那么它几乎肯定需要全部三个。1
2
3
4
5
6
7
8
9
10
11
12
13class MyLockGuard {
public:
using mutext_type = T;
explicit MyLockGuard(T t_mutex) : _MyMutex(t_mutex) { _MyMutex.lock(); }
MyLockGuard(T& _Mtx, std::adopt_lock_t) noexcept : _MyMutex(_Mtx) {}
MyLockGuard(const MyLockGuard&) = delete;
MyLockGuard& operator=(const MyLockGuard&) = delete;
~MyLockGuard() noexcept { _MyMutex.unlock(); }
private:
T& _MyMutex;
};
五复制
因为用户定义(包括 = default 或 = delete)的析构函数、复制构造函数或复制赋值运算符,会阻止隐式定义移动构造函数和移动赋值运算符,所以任何想要移动语义的类必须声明全部五个特殊成员函数
与三原则不同的是,不提供移动构造函数和移动赋值运算符通常不是错误,但会损失性能。
零原则
有自定义析构函数、复制/移动构造函数或复制/移动赋值运算符的类应该专门处理所有权(这遵循单一责任原则)。其他类都不应该拥有自定义的析构函数、复制/移动构造函数或复制/移动赋值运算符
当有意将某个基类用于多态用途时,可能需要将它的析构函数声明为 public 和 virtual。由于这会阻止生成隐式移动(并弃用隐式复制),因此必须将各特殊成员函数定义为 = default
类模板实参推导(CTAD)
为了实例化一个类模板,需要知晓每个模板实参,但并非每个模板实参都必须指定。在下列语境中,编译器会从初始化式的类型推导缺失的模板实参:
- 任意指定变量及变量模板的初始化的声明,其声明的类型是类模板(可有 cv 限定)
具名返回值优化
ADL
未定义行为
常用STL
STL包括容器,适配器(Adapter),迭代器(iterator)以及算法等.
组件 | 描述 |
---|---|
容器(Containers) | 容器是 STL 中最基本的组件之一,提供了各种数据结构,包括向量(vector)、链表(list)、队列(queue)、栈(stack)、集合(set)、映射(map)等。这些容器具有不同的特性和用途,可以根据实际需求选择合适的容器。 |
算法(Algorithms) | STL 提供了大量的算法,用于对容器中的元素进行各种操作,包括排序、搜索、复制、移动、变换等。这些算法在使用时不需要关心容器的具体类型,只需要指定要操作的范围即可。 |
迭代器(iterators) | 迭代器用于遍历容器中的元素,允许以统一的方式访问容器中的元素,而不用关心容器的内部实现细节。STL 提供了多种类型的迭代器,包括随机访问迭代器、双向迭代器、前向迭代器和输入输出迭代器等。 |
函数对象(Function Objects) | 函数对象是可以像函数一样调用的对象,可以用于算法中的各种操作。STL 提供了多种函数对象,包括一元函数对象、二元函数对象、谓词等,可以满足不同的需求。 |
适配器(Adapters) | 适配器用于将一种容器或迭代器适配成另一种容器或迭代器,以满足特定的需求。STL 提供了多种适配器,包括栈适配器(stack adapter)、队列适配器(queue adapter)和优先队列适配器(priority queue adapter)等。 |
容器
容器是用来存储数据的序列,它们提供了不同的存储方式和访问模式。
STL 中的容器可以分为三类:
1、序列容器:存储元素的序列,允许双向遍历。
- std::vector:动态数组,支持快速随机访问。
- std::deque:双端队列,支持快速插入和删除。
- std::list:链表,支持快速插入和删除,但不支持随机访问。
2、关联容器:存储键值对,每个元素都有一个键(key)和一个值(value),并且通过键来组织元素。
- std::set:集合,不允许重复元素。(有序的关联容器。它存储唯一的元素,并且这些元素总是按照一定的顺序进行排序,底层实现通常是通过一种自平衡二叉搜索树(通常是红黑树)实现的)
- std::multiset:多重集合,允许多个元素具有相同的键。
- std::map:映射,每个键映射到一个值。
- std::multimap:多重映射,存储了键值对(pair),其中键是唯一的,但值可以重复,允许一个键映射到多个值。
3、无序容器(C++11 引入):哈希表,支持快速的查找、插入和删除。
- std::unordered_set:无序集合(内部实现是一个哈希表,提供了平均常数时间复杂度的访问效率,但不维护任何特定的顺序)。
- std::unordered_multiset:无序多重集合。
- std::unordered_map:无序映射。
- std::unordered_multimap:无序多重映射
Beyond algorithm
C++推出的ranges和views使得操作数据更加简单.
Ranges 是一个可以遍历的元素序列,它可以是有限的也可以是无限的。与传统的迭代器对不同,Ranges提供了更高层次的抽象,使得代码更加简洁易读。Ranges支持各种操作如过滤、变换等,而不需要手动管理迭代器。
Views 是轻量级的视图对象,它们不拥有数据而是提供了一种查看或转换现有数据的方式。Views是惰性求值的,这意味着它们只在需要时计算结果,这有助于节省内存并提高性能。
- 常用Views操作
views::filter
: 根据给定谓词过滤元素。views::transform
: 对每个元素应用给定函数。views::take
: 获取前N个元素。views::drop
: 跳过前N个元素。