杂项 
  
一种面向对象实现 
- 将每个资源封装入一个类,其中: 
- 构造函数请求资源,并建立所有类不变式,或在它无法完成时抛出异常,
 - 析构函数释放资源并且决不会抛出异常;
 
 - 在使用资源时始终通过 
 类的满足以下要求的实例:- 自身拥有自动存储期或临时生存期;
 - 或具有与自动或临时对象的生存期绑定的生存期。
 
 
C++ 的智能指针等就是对 
C++ STL 
C++ 本身提供了一套标准模板库(
前面提及过 <memory>、<optional>、<variant>、<any> 等库,下面再简单介绍几个常用的模版库。
<vector> 
<vector> 主要提供了一个动态的连续数组 vector 的实现。vector 是一个自主动态管理内存的数组,其大小可以动态增长。vector 的时间复杂度与普通数组相近,提供 push_back 和 pop_back),和 insert 和 erase)。
vector 具有一个对应的迭代器,可以通过迭代器来访问 vector 中的元素。对于 vector v,v.begin() 返回指向第一个元素的迭代器,v.end() 返回指向最后一个元素的下一个位置的迭代器。遍历的范式如:for(auto it = v.begin(); it != v.end(); it++)。这种遍历方式提供了更多的灵活性,例如:
- 如果需要修改 
vector中的元素,可以通过*it来访问迭代器指向的元素。 - 如果希望逆序遍历 
vector,可以使用v.rbegin()和v.rend()。 - 如果希望在遍历过程中删除元素,可以使用 
v.erase(it)。但是需要注意,删除元素后,原先的it迭代器将失效,需要用erase的返回值重新赋值。 - 如果希望在遍历过程中插入元素,可以使用 
v.insert(it, val)。同样,插入元素后,原先的it迭代器将失效。 
另一方面,vector 也可以看作简单的数组,可以通过 v[i] 来访问第 i 个元素,通过 v.size() 来获取 vector 的大小。遍历的范式如:for(int i = 0; i < v.size(); i++)。
此外,可以利用 sort 函数对 vector 进行排序,例如 sort(v.begin(), v.end())。 还可以在 sort 函数中传入一个比较函数,来实现自定义排序。
自定义比较函数
对于 vector<T> v,可以通过 sort(v.begin(), v.end(), cmp) 来实现自定义排序。其中 cmp 是一个比较函数,其定义如下:
bool cmp(const T& a, const T& b) {
    // return true if a should be before b
    // return false if a should be after b
}2
3
4
即,如果 a 应当在 b 之前,则返回 true,否则返回 false。
下面是一个简单的 vector 的使用示例:
vector<int> v;
v.push_back(1);
v.push_back(2); // adding element at rear. v = {1, 2}
v.push_back(3); // adding element at rear. v = {1, 2, 3}
v.pop_back(); // removing element from rear. v = {1, 2}
for(auto it = v.begin(); it != v.end(); it++) {
    cout << *it << " "; // output: 1 2
}
for(int i = 0; i < v.size(); i++) {
    cout << v[i] << " "; // output: 1 2
}
for(auto it = v.rbegin(); it != v.rend(); it++) {
    cout << *it << " "; // output: 2 1
}
// remove all elements with value 1
for(auto it = v.begin(); it != v.end(); ) {
    if(*it == 1) {
        it = v.erase(it); // remove element 1 and return the next iterator
    }else {
        it++;
    }
}
// insert element 4 at the beginning
v.insert(v.begin(), 4); // v = {4, 2}
// sort the vector
sort(v.begin(), v.end()); // v = {2, 4}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<map> 
<map> 提供了一个键唯一的键值对容器 map。map 是一个有序的容器,其内部实现一般是红黑树。map 提供 
可以使用 map<T1, T2> 来定义一个 map,其中 T1 是键的类型,T2 是值的类型。map 的操作类似于 vector,对于 map 对象 m,可以通过 m[key] 来访问 map 中的元素,通过 m.size() 来获取 map 的大小。同样,map 容器包含一个迭代器,遍历的范式如:for(auto it = m.begin(); it != m.end(); it++)。
常用的操作有:
- 如果希望寻找 
map中是否存在某个键,可以使用m.find(key),返回一个迭代器,如果找到了,返回指向该键值对的迭代器,否则返回m.end()。 - 如果希望插入元素或若键已存在则赋值给当前元素,可以使用 
m.insert_or_assign(key, val)。 还可以使用类似数组的方式m[key] = val来插入或重新赋值元素。 
集合容器
set.h 与 map.h 类似,提供了一个键值合一的集合容器 set。set 容器维护了一个集合,其中的元素是唯一的,可以对 set 进行插入、删除和查找操作,但是不支持通过下标访问元素。
<queue> 
<queue> 中主要提供了一个优先队列(堆,且默认为大根堆) priority_queue 的实现。它提供了 
可以使用 priority_queue<T> 来定义一个 priority_queue,其中 T 是队列中元素的类型。
常用的操作有:
- 如果希望插入元素,可以使用 
q.push(val)。 - 如果希望删除队首元素(即最大元素),可以使用 
q.pop()。 - 如果希望查找队首元素,可以使用 
q.top()。 - 如果希望判断队列是否为空,可以使用 
q.empty()。 - 如果希望获取队列的大小,可以使用 
q.size()。 
自定义比较函数
对于 priority_queue<T>,可以通过 **priority_queue<T, vector<T>, cmp>** 来实现自定义排序。其中 cmp 是一个比较函数,其定义如下(与 sort 的比较相近):
bool cmp(const T& a, const T& b) {
    // return true if a should be before b
    // return false if a should be after b
}2
3
4
<sstream> 
提供字符串流。主要应用为字符串分割。
// split string by delimiter
std::vector<std::string> splitString(const std::string& str, char delimiter) {
    std::vector<std::string> tokens;
    std::stringstream ss(str);
    std::string token;
    while (std::getline(ss, token, delimiter)) {
        tokens.push_back(token);
    }
    return tokens;
}2
3
4
5
6
7
8
9
10
11
12
<cctype> 
主要用于字符处理,提供了一些字符分类和字符转换的函数。常用的函数有:isalpha、isdigit、isalnum(字母或数字)、islower、isupper、tolower、toupper 等等。
<chrono> 
主要用于时间处理的复杂操作,提供了一些时间点和时间段的类。如果不需要复杂的时间处理,可以使用 <ctime> 库。
