现代C++实战:用STL替代传统设计模式

1.STL 简介与概述

STL(Standard Template Library)是C++标准库的核心组成部分,提供了一系列通用的模板类和函数,实现了常用的数据结构和算法。

核心组件:

  • 容器(Containers):管理数据的集合
  • 迭代器(Iterators):访问容器元素的通用方法
  • 算法(Algorithms):操作数据的通用函数
  • 函数对象(Functors):使算法更灵活的可调用对象

设计理念:

  • 泛型编程
  • 组件的高度可复用性
  • 效率与抽象的平衡
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> v = {7, 3, 5, 1, 9};
    std::sort(v.begin(), v.end());
    for (int i : v) {
        std::cout << i << " ";
    }
    return 0;
}

2.容器(Containers)

序列式容器

vector:动态数组,支持快速随机访问

std::vector<int> vec = {1, 2, 3};
vec.push_back(4);  // 添加元素

deque:双端队列,支持首尾快速插入删除

std::deque<int> dq = {2, 3, 4};
dq.push_front(1);  // 前端插入

list:双向链表

std::list<int> lst = {1, 2, 3};
lst.splice(lst.begin(), lst, ++lst.begin());  // 移动元素

forward_list:单向链表(C++11)

std::forward_list<int> flst = {1, 2, 3};
flst.push_front(0);  // 只能前端插入

array:固定大小数组(C++11)

std::array<int, 3> arr = {1, 2, 3};

关联式容器

set:有序唯一元素集合

std::set<int> s = {3, 1, 4, 1};
// s = {1, 3, 4}

multiset:有序可重复元素集合

std::multiset<int> ms = {3, 1, 4, 1};
// ms = {1, 1, 3, 4}

map:键值对集合,键唯一有序

std::map<std::string, int> m = {{"Alice", 25}, {"Bob", 30}};

multimap:键值对集合,键可重复有序

std::multimap<std::string, int> mm = {{"Alice", 25}, {"Alice", 26}};

无序关联式容器

unordered_set:哈希集合

std::unordered_set<int> us = {3, 1, 4, 1};

unordered_multiset:哈希多重集合

std::unordered_multiset<int> ums = {3, 1, 4, 1};

unordered_map:哈希映射

std::unordered_map<std::string, int> um = {{"Alice", 25}, {"Bob", 30}};

unordered_multimap:哈希多重映射

std::unordered_multimap<std::string, int> umm = {{"Alice", 25}, {"Alice", 26}};

容器适配器

stack:LIFO栈

std::stack<int> s;
s.push(1); s.pop();

queue:FIFO队列

std::queue<int> q;
q.push(1); q.pop();

priority_queue:优先级队列

std::priority_queue<int> pq;
pq.push(3); pq.push(1);  // 3先出

3.迭代器(Iterators)

迭代器是STL中连接容器和算法的桥梁,提供了一种统一的方法来遍历容器元素。
迭代器类别:

  • 输入迭代器
  • 输出迭代器
  • 前向迭代器
  • 双向迭代器
  • 随机访问迭代器
std::vector<int> v = {1, 2, 3, 4, 5};

// 使用迭代器遍历
for (auto it = v.begin(); it != v.end(); ++it) {
    std::cout << *it << " ";
}

// 反向迭代器
for (auto rit = v.rbegin(); rit != v.rend(); ++rit) {
    std::cout << *rit << " ";
}

// 常量迭代器
for (auto cit = v.cbegin(); cit != v.cend(); ++cit) {
    // *cit = 10;  // 错误,不能修改
}

4.算法(Algorithms)

STL提供了大量通用算法,这些算法通过迭代器操作容器元素。
常用算法分类:
非修改序列操作:

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

// 查找
auto it = std::find(v.begin(), v.end(), 3);

// 计数
int cnt = std::count(v.begin(), v.end(), 2);

// 条件计数
cnt = std::count_if(v.begin(), v.end(), [](int x){ return x > 2; });

修改序列操作:

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

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

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

// 第n元素
std::nth_element(v.begin(), v.begin() + 2, v.end());

// 二分查找
bool found = std::binary_search(v.begin(), v.end(), 3);

排序与相关操作:

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

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

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

// 第n元素
std::nth_element(v.begin(), v.begin() + 2, v.end());

// 二分查找
bool found = std::binary_search(v.begin(), v.end(), 3);

数值算法:

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

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

// 内积
int product = std::inner_product(v.begin(), v.end(), v.begin(), 0);

// 相邻差
std::adjacent_difference(v.begin(), v.end(), v.begin());

5.函数对象(Functors)

函数对象是重载了operator()的类对象,可以像函数一样被调用
内置函数对象:

#include <functional>

std::plus<int> add;
int sum = add(3, 4);  // 7

std::greater<int> gt;
bool result = gt(5, 3);  // true

自定义函数对象:

struct Square {
    int operator()(int x) const {
        return x * x;
    }
};

Square sq;
int squared = sq(5);  // 25

Lambda表达式(C++11):

auto lambda = [](int x) { return x * x; };
int result = lambda(5);  // 25

std::vector<int> v = {1, 2, 3, 4, 5};
std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; });

6.智能指针(Smart Pointers)

unique_ptr:独占所有权指针

std::unique_ptr<int> ptr(new int(10));
// auto ptr = std::make_unique<int>(10);  // C++14

shared_ptr:共享所有权指针

std::shared_ptr<int> ptr1 = std::make_shared<int>(20);
auto ptr2 = ptr1;  // 引用计数增加

weak_ptr:弱引用指针

std::shared_ptr<int> shared = std::make_shared<int>(30);
std::weak_ptr<int> weak = shared;

if (auto temp = weak.lock()) {
    // 使用temp
}

7.STL 高级特性

分配器(Allocators):

std::vector<int, MyAllocator<int>> v;

类型特性(Type Traits):

static_assert(std::is_integral<int>::value, "int is integral");

移动语义与完美转发:

std::vector<std::string> v;
v.push_back(std::move(str));  // 移动而非拷贝

8.STL 性能与最佳实践

容器选择指南:

  • 需要随机访问:vector, deque, array
  • 频繁插入删除中间元素:list, forward_list
  • 快速查找:set/map或unordered_set/unordered_map
  • FIFO/LIFO:queue/stack

效率提示:

  • 预分配空间(vector::reserve)
  • 使用emplace代替insert
  • 利用移动语义
  • 选择合适的算法复杂度

9.C++11/14/17/20 中的STL新特性

C++11:

  • 移动语义支持

  • 无序容器

  • 智能指针

  • 正则表达式

  • 线程支持库

C++14:

  • 泛型lambda
  • make_unique
  • 改进的constexpr

C++17:

  • 并行STL算法
  • std::optional, std::variant, std::any
  • 文件系统库
  • string_view

C++20:

  • 范围(Ranges)
  • 概念(Concepts)
  • 协程(Coroutines)
  • 格式化库(std::format)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值