第28章 标准库详解

标准库概述

C++标准库是C++语言的核心组成部分,提供了丰富的工具和组件,用于简化常见编程任务,提高代码质量和可维护性。标准库的设计遵循以下原则:

  • 高性能:组件设计注重效率,避免不必要的开销
  • 可移植性:跨平台兼容,确保代码在不同环境下的一致性
  • 安全性:提供类型安全的接口,减少运行时错误
  • 可扩展性:设计灵活,支持用户自定义扩展

标准库的组织结构

C++标准库可分为以下几个主要部分:

组件描述头文件示例
核心语言支持语言特性的直接支持<cstddef>, <limits>
容器库数据结构实现<vector>, <map>, <unordered_map>
算法库通用算法实现<algorithm>, <numeric>
迭代器库迭代器类型和操作<iterator>
工具库通用工具和辅助类<utility>, <functional>, <memory>
字符串库字符串处理<string>, <string_view>
流库输入/输出操作<iostream>, <fstream>
本地化库国际化支持<locale>
正则表达式模式匹配<regex>
文件系统文件和目录操作<filesystem>
线程支持并发编程<thread>, <mutex>
原子操作无锁编程<atomic>
时间库时间和日期处理<chrono>
随机数随机数生成<random>
数学库数学函数<cmath>
范围库范围操作(C++20+)<ranges>

核心语言支持库

核心语言支持库提供了C++语言基本特性的支持,包括类型定义、宏和函数。

类型和常量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <cstddef>   // 定义size_t, ptrdiff_t等类型
#include <cstdint> // 定义固定宽度整数类型
#include <limits> // 数值类型的极限值
#include <climits> // 整数类型的极限值
#include <cfloat> // 浮点类型的极限值

int main() {
// 类型大小
std::cout << "size_t: " << sizeof(std::size_t) << " bytes" << std::endl;
std::cout << "ptrdiff_t: " << sizeof(std::ptrdiff_t) << " bytes" << std::endl;

// 固定宽度整数
std::cout << "int32_t: " << sizeof(std::int32_t) << " bytes" << std::endl;
std::cout << "uint64_t: " << sizeof(std::uint64_t) << " bytes" << std::endl;

// 数值极限
std::cout << "int min: " << std::numeric_limits<int>::min() << std::endl;
std::cout << "int max: " << std::numeric_limits<int>::max() << std::endl;
std::cout << "double epsilon: " << std::numeric_limits<double>::epsilon() << std::endl;

return 0;
}

错误处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <cassert>   // 断言
#include <cerrno> // 错误码
#include <system_error> // 系统错误(C++11+)

int main() {
// 断言
int x = 5;
assert(x > 0 && "x must be positive");

// 错误码
errno = 0;
// 执行可能设置errno的操作

// 系统错误
try {
throw std::system_error(std::error_code(ENOENT, std::generic_category()), "File not found");
} catch (const std::system_error& e) {
std::cout << "Error: " << e.what() << std::endl;
std::cout << "Error code: " << e.code() << std::endl;
}

return 0;
}

容器库

容器库提供了各种数据结构的实现,用于存储和组织数据。

序列容器

1
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
#include <vector>    // 动态数组
#include <list> // 双向链表
#include <deque> // 双端队列
#include <array> // 固定大小数组(C++11+)
#include <forward_list> // 单向链表(C++11+)

int main() {
// vector - 动态数组,随机访问快
std::vector<int> v = {1, 2, 3, 4, 5};
v.push_back(6);
v.pop_back();

// list - 双向链表,插入删除快
std::list<int> l = {1, 2, 3};
l.push_front(0);
l.push_back(4);

// deque - 双端队列,两端插入删除快
std::deque<int> d = {1, 2, 3};
d.push_front(0);
d.push_back(4);

// array - 固定大小数组,编译期大小
std::array<int, 5> a = {1, 2, 3, 4, 5};

// forward_list - 单向链表,空间效率更高
std::forward_list<int> fl = {1, 2, 3};
fl.push_front(0);

return 0;
}

关联容器

1
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
#include <set>       // 有序集合
#include <map> // 有序映射
#include <unordered_set> // 无序集合(C++11+)
#include <unordered_map> // 无序映射(C++11+)
#include <multiset> // 有序多重集合
#include <multimap> // 有序多重映射

int main() {
// set - 有序集合,自动排序,无重复元素
std::set<int> s = {3, 1, 4, 1, 5, 9};

// map - 有序映射,键值对,自动按键排序
std::map<std::string, int> m;
m["one"] = 1;
m["two"] = 2;

// unordered_set - 无序集合,哈希表实现,查找更快
std::unordered_set<int> us = {3, 1, 4, 1, 5, 9};

// unordered_map - 无序映射,哈希表实现,查找更快
std::unordered_map<std::string, int> um;
um["one"] = 1;
um["two"] = 2;

// multiset - 有序多重集合,允许重复元素
std::multiset<int> ms = {3, 1, 4, 1, 5, 9};

// multimap - 有序多重映射,允许重复键
std::multimap<std::string, int> mm;
mm.insert({"one", 1});
mm.insert({"one", 10});

return 0;
}

容器适配器

1
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
#include <stack>     // 栈
#include <queue> // 队列
#include <priority_queue> // 优先队列

int main() {
// stack - LIFO(后进先出)
std::stack<int> st;
st.push(1);
st.push(2);
st.pop();

// queue - FIFO(先进先出)
std::queue<int> q;
q.push(1);
q.push(2);
q.pop();

// priority_queue - 优先队列,最大元素优先
std::priority_queue<int> pq;
pq.push(3);
pq.push(1);
pq.push(4);
// 顶部元素是4

return 0;
}

算法库

算法库提供了大量通用算法,可用于各种容器和数据结构。

查找和搜索

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <algorithm>
#include <vector>

int main() {
std::vector<int> v = {1, 3, 5, 7, 9};

// 线性查找
auto it = std::find(v.begin(), v.end(), 5);
if (it != v.end()) {
std::cout << "Found: " << *it << std::endl;
}

// 二分查找(要求有序)
bool found = std::binary_search(v.begin(), v.end(), 5);

// 查找第一个大于等于给定值的元素
auto lower = std::lower_bound(v.begin(), v.end(), 4);

// 查找第一个大于给定值的元素
auto upper = std::upper_bound(v.begin(), v.end(), 5);

return 0;
}

排序和修改

1
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
#include <algorithm>
#include <vector>

int main() {
std::vector<int> v = {5, 2, 9, 1, 5, 6};

// 排序
std::sort(v.begin(), v.end());

// 稳定排序
std::stable_sort(v.begin(), v.end());

// 部分排序
std::partial_sort(v.begin(), v.begin() + 3, v.end());

// 排序并去重
std::sort(v.begin(), v.end());
auto last = std::unique(v.begin(), v.end());
v.erase(last, v.end());

// 翻转
std::reverse(v.begin(), v.end());

// 旋转
std::rotate(v.begin(), v.begin() + 1, v.end());

return 0;
}

数值算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <numeric>
#include <vector>

int main() {
std::vector<int> v = {1, 2, 3, 4, 5};

// 累加
int sum = std::accumulate(v.begin(), v.end(), 0);

// 累加(自定义操作)
int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>());

// 相邻差值
std::vector<int> diffs(v.size() - 1);
std::adjacent_difference(v.begin(), v.end(), diffs.begin());

// 前缀和
std::vector<int> prefix_sums(v.size());
std::partial_sum(v.begin(), v.end(), prefix_sums.begin());

return 0;
}

范围算法(C++20+)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <algorithm>
#include <ranges>
#include <vector>

int main() {
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

// 过滤并转换
auto result = v | std::views::filter([](int x) { return x % 2 == 0; })
| std::views::transform([](int x) { return x * 2; });

// 遍历结果
for (int x : result) {
std::cout << x << " ";
}

return 0;
}

工具库

工具库提供了各种通用工具和辅助类,支持标准库的其他部分。

通用工具

1
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
#include <utility>   // 实用工具
#include <tuple> // 元组(C++11+)
#include <optional> // 可选值(C++17+)
#include <variant> // 变体类型(C++17+)
#include <any> // 任意类型(C++17+)

int main() {
// pair - 键值对
std::pair<int, std::string> p(1, "one");

// tuple - 多值组合
std::tuple<int, std::string, double> t(1, "one", 1.1);
int first = std::get<0>(t);

// optional - 可选值
std::optional<int> opt = 42;
if (opt.has_value()) {
std::cout << "Value: " << opt.value() << std::endl;
}

// variant - 类型安全的联合
std::variant<int, std::string> var = 42;
var = "hello";

// any - 任意类型
std::any a = 42;
a = std::string("hello");

return 0;
}

函数对象

1
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
#include <functional> // 函数对象

int add(int a, int b) {
return a + b;
}

class Multiply {
public:
int operator()(int a, int b) const {
return a * b;
}
};

int main() {
// 函数指针
int (*func_ptr)(int, int) = add;

// 函数对象
Multiply multiply;

// 绑定器
auto add5 = std::bind(add, std::placeholders::_1, 5);

// 函数包装器
std::function<int(int, int)> f = add;
f = multiply;

return 0;
}

内存管理

1
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
#include <memory>    // 智能指针

class Resource {
public:
Resource() { std::cout << "Resource created" << std::endl; }
~Resource() { std::cout << "Resource destroyed" << std::endl; }
void use() { std::cout << "Resource used" << std::endl; }
};

int main() {
// unique_ptr - 独占所有权
std::unique_ptr<Resource> up1(new Resource());
std::unique_ptr<Resource> up2 = std::make_unique<Resource>();

// shared_ptr - 共享所有权
std::shared_ptr<Resource> sp1(new Resource());
std::shared_ptr<Resource> sp2 = std::make_shared<Resource>();
std::shared_ptr<Resource> sp3 = sp2;

// weak_ptr - 不增加引用计数的shared_ptr观察者
std::weak_ptr<Resource> wp = sp2;
if (auto locked = wp.lock()) {
locked->use();
}

return 0;
}

字符串库

字符串库提供了字符串处理的功能,包括std::string和C++17引入的std::string_view

字符串操作

1
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
#include <string>
#include <string_view> // C++17+

int main() {
// 字符串创建
std::string s1 = "Hello";
std::string s2(5, 'a');
std::string s3(s1);

// 字符串操作
s1 += " World";
s1.append("!");

// 字符串查找
size_t pos = s1.find("World");
if (pos != std::string::npos) {
std::cout << "Found at position: " << pos << std::endl;
}

// 字符串子串
std::string sub = s1.substr(6, 5); // "World"

// 字符串转换
int num = std::stoi("42");
double d = std::stod("3.14");
std::string num_str = std::to_string(42);

// string_view - 非拥有的字符串视图
std::string_view sv = s1;
std::string_view sv2 = "Hello";

return 0;
}

流库

流库提供了输入/输出操作的功能,包括标准输入/输出、文件操作和字符串流。

标准输入/输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <iomanip>

int main() {
// 标准输出
std::cout << "Hello, World!" << std::endl;

// 格式化输出
std::cout << std::fixed << std::setprecision(2);
std::cout << "Pi: " << 3.14159 << std::endl;

// 标准输入
int x;
std::cout << "Enter a number: ";
std::cin >> x;

// 错误处理
if (std::cin.fail()) {
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Invalid input!" << std::endl;
}

return 0;
}

文件操作

1
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
#include <fstream>

int main() {
// 写入文件
std::ofstream outfile("example.txt");
if (outfile.is_open()) {
outfile << "Hello, File!" << std::endl;
outfile.close();
}

// 读取文件
std::ifstream infile("example.txt");
if (infile.is_open()) {
std::string line;
while (std::getline(infile, line)) {
std::cout << line << std::endl;
}
infile.close();
}

// 二进制文件
std::ofstream binfile("data.bin", std::ios::binary);
int data = 42;
binfile.write(reinterpret_cast<char*>(&data), sizeof(data));
binfile.close();

return 0;
}

字符串流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <sstream>

int main() {
// 输出字符串流
std::ostringstream oss;
oss << "Hello, " << "String Stream!" << std::endl;
std::string str = oss.str();

// 输入字符串流
std::string input = "123 456 789";
std::istringstream iss(input);
int a, b, c;
iss >> a >> b >> c;

// 类型转换
std::string num_str = "12345";
std::istringstream iss2(num_str);
int num;
iss2 >> num;

return 0;
}

文件系统库

C++17引入的文件系统库提供了跨平台的文件和目录操作功能。

文件系统操作

1
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

int main() {
// 当前路径
fs::path current_path = fs::current_path();
std::cout << "Current path: " << current_path << std::endl;

// 创建目录
fs::path dir_path = current_path / "test_dir";
if (!fs::exists(dir_path)) {
fs::create_directory(dir_path);
}

// 创建嵌套目录
fs::path nested_path = dir_path / "subdir1" / "subdir2";
fs::create_directories(nested_path);

// 遍历目录
for (const auto& entry : fs::directory_iterator(current_path)) {
std::cout << entry.path() << " "
<< (fs::is_directory(entry.status()) ? "[dir]" : "[file]") << std::endl;
}

// 文件状态
fs::path file_path = current_path / "example.txt";
if (fs::exists(file_path)) {
std::cout << "File size: " << fs::file_size(file_path) << " bytes" << std::endl;
std::cout << "Last write time: " << fs::last_write_time(file_path).time_since_epoch().count() << std::endl;
}

// 重命名和移动
fs::path old_path = dir_path / "old.txt";
fs::path new_path = dir_path / "new.txt";
if (fs::exists(old_path)) {
fs::rename(old_path, new_path);
}

// 删除
if (fs::exists(new_path)) {
fs::remove(new_path);
}
if (fs::exists(dir_path)) {
fs::remove_all(dir_path);
}

return 0;
}

时间库

C++11引入的时间库提供了时间和日期处理的功能。

时间点和时长

1
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
#include <chrono>
#include <iostream>

int main() {
// 系统时钟
using namespace std::chrono;

// 当前时间点
auto now = system_clock::now();

// 时间点转换为时间_t
std::time_t now_c = system_clock::to_time_t(now);
std::cout << "Current time: " << std::ctime(&now_c);

// 时长
seconds sec(1);
milliseconds ms = sec;
microseconds us = ms;
nanoseconds ns = us;

// 时间计算
auto future = now + hours(1);
auto duration = future - now;
std::cout << "Duration in seconds: "
<< duration_cast<seconds>(duration).count() << std::endl;

// 睡眠
std::this_thread::sleep_for(milliseconds(500));

return 0;
}

时钟

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <chrono>

int main() {
// 系统时钟 - 真实时间
using system_clock = std::chrono::system_clock;

// 稳态时钟 - 单调递增,不受系统时间调整影响
using steady_clock = std::chrono::steady_clock;

// 高精度时钟 - 系统支持的最高精度时钟
using high_resolution_clock = std::chrono::high_resolution_clock;

// 计时示例
auto start = steady_clock::now();

// 执行一些操作
for (int i = 0; i < 1000000; ++i) {
// 空循环
}

auto end = steady_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

return 0;
}

随机数库

C++11引入的随机数库提供了高质量的随机数生成功能。

随机数生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <random>
#include <iostream>

int main() {
// 随机数引擎
std::random_device rd; // 非确定性行为
std::mt19937 gen(rd()); // Mersenne Twister引擎

// 分布
std::uniform_int_distribution<> dist(1, 100); // 均匀整数分布
std::uniform_real_distribution<> real_dist(0.0, 1.0); // 均匀实数分布
std::normal_distribution<> norm_dist(0.0, 1.0); // 正态分布

// 生成随机数
for (int i = 0; i < 5; ++i) {
std::cout << "Random int: " << dist(gen) << std::endl;
std::cout << "Random real: " << real_dist(gen) << std::endl;
std::cout << "Random normal: " << norm_dist(gen) << std::endl;
}

return 0;
}

线程支持库

C++11引入的线程支持库提供了并发编程的功能。

线程创建和管理

1
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
#include <thread>
#include <iostream>
#include <vector>

void print_number(int n) {
std::cout << "Number: " << n << std::endl;
}

int main() {
// 创建线程
std::thread t1(print_number, 42);

// 等待线程完成
t1.join();

// detach线程(不等待其完成)
std::thread t2(print_number, 100);
t2.detach();

// 线程池示例
std::vector<std::thread> threads;
for (int i = 0; i < 5; ++i) {
threads.emplace_back(print_number, i);
}

// 等待所有线程完成
for (auto& t : threads) {
t.join();
}

return 0;
}

同步原语

1
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <iostream>

std::mutex mtx;
std::condition_variable cv;
std::queue<int> tasks;
bool done = false;

void producer() {
for (int i = 0; i < 5; ++i) {
{
std::lock_guard<std::mutex> lock(mtx);
tasks.push(i);
std::cout << "Produced: " << i << std::endl;
}
cv.notify_one(); // 通知一个等待的线程
}

{
std::lock_guard<std::mutex> lock(mtx);
done = true;
}
cv.notify_all(); // 通知所有等待的线程
}

void consumer() {
while (true) {
std::unique_lock<std::mutex> lock(mtx);

// 等待直到队列非空或任务完成
cv.wait(lock, []{ return !tasks.empty() || done; });

if (tasks.empty() && done) {
break;
}

int task = tasks.front();
tasks.pop();
lock.unlock(); // 解锁以允许其他线程访问队列

std::cout << "Consumed: " << task << std::endl;
}
}

int main() {
std::thread prod(producer);
std::thread cons(consumer);

prod.join();
cons.join();

return 0;
}

标准库最佳实践

容器选择

场景推荐容器原因
随机访问频繁,需要动态大小std::vector连续内存,缓存友好,随机访问O(1)
频繁在中间插入/删除std::liststd::forward_list链表结构,插入/删除O(1)
需要两端操作std::deque两端插入/删除O(1),随机访问O(1)
固定大小数组std::array编译期大小,栈分配,性能好
查找频繁,需要有序std::set / std::map红黑树实现,查找O(log n)
查找频繁,不需要有序std::unordered_set / std::unordered_map哈希表实现,平均查找O(1)
需要按优先级处理元素std::priority_queue堆实现,获取最高优先级元素O(1)

性能优化

  1. 避免不必要的拷贝:使用移动语义和引用
  2. 预分配内存:对std::vector使用reserve()
  3. 选择合适的算法:根据具体需求选择最优算法
  4. 使用视图而非拷贝:如std::string_view(C++17+)
  5. 避免动态内存分配:优先使用栈分配和对象池
  6. 利用编译期计算:使用constexpr和模板元编程
  7. 并行处理:对于大型数据集,考虑使用并行算法(C++17+)

安全性

  1. 使用智能指针:避免内存泄漏和悬空指针
  2. 边界检查:使用at()而非operator[]进行边界检查
  3. 异常安全:确保代码在异常情况下仍能保持一致状态
  4. 类型安全:避免使用void*和类型转换
  5. 资源管理:使用RAII模式管理资源

代码风格

  1. 命名空间:在实现文件中使用using namespace std;,但在头文件中避免
  2. 包含顺序:标准库头文件在前,然后是第三方库,最后是本地头文件
  3. 代码组织:将相关功能分组,使用清晰的注释
  4. 一致性:保持代码风格一致,包括缩进、命名和格式

标准库高级主题

自定义分配器

1
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
35
36
37
38
39
40
41
42
43
44
45
46
#include <memory>
#include <vector>

// 简单的自定义分配器
template <typename T>
class MyAllocator {
public:
using value_type = T;

MyAllocator() noexcept = default;

template <typename U>
MyAllocator(const MyAllocator<U>&) noexcept {}

T* allocate(std::size_t n) {
if (n > std::size_t(-1) / sizeof(T)) {
throw std::bad_alloc();
}
if (auto p = static_cast<T*>(std::malloc(n * sizeof(T)))) {
return p;
}
throw std::bad_alloc();
}

void deallocate(T* p, std::size_t) noexcept {
std::free(p);
}
};

template <typename T, typename U>
bool operator==(const MyAllocator<T>&, const MyAllocator<U>&) noexcept {
return true;
}

template <typename T, typename U>
bool operator!=(const MyAllocator<T>&, const MyAllocator<U>&) noexcept {
return false;
}

int main() {
// 使用自定义分配器
std::vector<int, MyAllocator<int>> v;
v.push_back(42);

return 0;
}

类型擦除

1
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <memory>
#include <functional>
#include <iostream>

// 类型擦除接口
class Drawable {
public:
virtual ~Drawable() = default;
virtual void draw() const = 0;
};

// 类型擦除实现
template <typename T>
class DrawableImpl : public Drawable {
public:
DrawableImpl(T t) : obj(std::move(t)) {}
void draw() const override {
obj.draw();
}
private:
T obj;
};

// 类型擦除包装器
class AnyDrawable {
public:
template <typename T>
AnyDrawable(T t) : impl(std::make_unique<DrawableImpl<T>>(std::move(t))) {}

void draw() const {
impl->draw();
}
private:
std::unique_ptr<Drawable> impl;
};

// 可绘制类型
class Circle {
public:
void draw() const {
std::cout << "Drawing a circle" << std::endl;
}
};

class Square {
public:
void draw() const {
std::cout << "Drawing a square" << std::endl;
}
};

int main() {
std::vector<AnyDrawable> drawables;
drawables.emplace_back(Circle());
drawables.emplace_back(Square());

for (const auto& d : drawables) {
d.draw();
}

return 0;
}

小结

C++标准库是一个功能丰富、设计精良的工具集,为C++程序员提供了从基础数据结构到高级并发工具的全方位支持。本章详细介绍了标准库的各个组成部分,包括:

  1. 核心语言支持:提供类型定义、错误处理等基础功能
  2. 容器库:实现各种数据结构,如向量、列表、映射等
  3. 算法库:提供排序、查找、数值计算等通用算法
  4. 工具库:包括智能指针、函数对象、元组等实用工具
  5. 字符串库:处理字符串和字符串视图
  6. 流库:实现输入/输出操作
  7. 文件系统库:提供跨平台的文件和目录操作
  8. 时间库:处理时间和日期
  9. 随机数库:生成高质量随机数
  10. 线程支持库:实现并发编程

掌握标准库的使用对于编写高效、可维护的C++代码至关重要。通过合理选择和使用标准库组件,开发者可以:

  • 提高开发效率:避免重复造轮子,利用成熟的实现
  • 提升代码质量:标准库经过广泛测试和优化,质量有保障
  • 增强可移植性:标准库确保代码在不同平台上的一致性
  • 优化性能:标准库组件通常经过性能优化

在实际编程中,应根据具体需求选择合适的标准库组件,并遵循最佳实践,以充分发挥C++语言的优势。

标准库是C++语言不断发展的重要部分,随着C++标准的更新(如C++17、C++20、C++23),标准库也在不断扩展和改进,为开发者提供更多现代、高效的工具。持续学习和掌握标准库的新特性,是成为优秀C++程序员的必经之路。