C++学习之旅【C++内存管理、模板初阶以及STL简介】
摘要:本文系统介绍了C++进阶三大核心知识:内存管理、模板编程和STL标准库。重点讲解了智能指针(unique_ptr/shared_ptr)的RAII机制,函数与类模板的泛型编程实现,以及STL容器(vector/map等)和算法的使用方法。文章通过代码示例对比了传统new/delete与现代智能指针的区别,分析了各类容器的适用场景,并强调了三者间的内在联系:内存管理是基础,模板支撑STL实现,
·
C++学习之旅:内存管理、模板初阶以及STL简介
恭喜你走到这一步!掌握了基础语法、函数、类与对象后,接下来这三大块——内存管理、模板(Template)和STL(标准模板库)——是真正让C++强大起来的核心能力。咱们一步一步来,轻松不迷路!
1. C++ 内存管理:new/delete 与 RAII 思想
C++ 没有垃圾回收(GC),内存完全由程序员手动管理,但现代C++提供了安全高效的机制。
原始方式:new 和 delete
int* p1 = new int; // 动态分配单个整数
int* arr = new int[10]; // 动态分配数组
*p1 = 42;
arr[0] = 100;
// 必须成对删除,否则内存泄漏!
delete p1; // 释放单个
delete[] arr; // 释放数组(必须加[])
常见错误:
- 忘记 delete → 内存泄漏
- delete 后继续使用 → 野指针(undefined behavior)
- new 和 delete 不匹配(new[] 却 delete)→ 未定义行为
现代C++推荐:智能指针 + RAII
RAII(Resource Acquisition Is Initialization):资源获取即初始化——构造函数申请资源,析构函数释放资源。
#include <memory> // 必须包含
std::unique_ptr<int> up1(new int(42)); // 独占所有权
std::unique_ptr<int> up2 = std::make_unique<int>(100); // 推荐写法,更安全
std::shared_ptr<int> sp1 = std::make_shared<int>(200); // 共享所有权,引用计数
std::shared_ptr<int> sp2 = sp1; // 计数+1
// 离开作用域自动释放,无需手动 delete!
智能指针对比表
| 智能指针 | 所有权 | 典型场景 | 关键函数 |
|---|---|---|---|
| unique_ptr | 独占 | 需要明确单一所有者的资源 | make_unique, reset |
| shared_ptr | 共享(引用计数) | 多个对象共享同一资源 | make_shared, use_count |
| weak_ptr | 弱引用 | 解决 shared_ptr 循环引用 | lock() 获取 shared_ptr |
实战建议:
- 永远优先使用
std::make_unique和std::make_shared(异常安全) - 裸 new/delete 只在极特殊情况(如实现自己的智能指针)使用
2. 模板初阶:泛型编程的起点
模板是C++泛型编程的基础,让你写出“类型无关”的代码。
函数模板
#include <iostream>
// 模板声明
template <typename T> // T 是类型参数
T max(T a, T b) {
return (a > b) ? a : b;
}
int main() {
std::cout << max(3, 7) << std::endl; // T 推导为 int
std::cout << max(3.14, 2.718) << std::endl; // T 推导为 double
std::cout << max('a', 'z') << std::endl; // T 推导为 char
return 0;
}
类模板
template <typename T, int SIZE = 10> // 可多个参数,默认参数
class Array {
T data[SIZE];
public:
T& operator[](int idx) { return data[idx]; }
};
Array<int> intArr; // SIZE 使用默认值 10
Array<double, 100> bigArr; // 指定 SIZE 为 100
显式指定类型
max<double>(3, 7.5); // 强制使用 double
关键点:
- 模板代码在编译期实例化(生成具体类型代码)
- 模板定义一般放在头文件(.h 或 .hpp),因为编译器需要看到完整定义
3. STL 简介:标准模板库,C++的“轮子”宝库
STL(Standard Template Library)是C++最强大的部分,包含三大组件:容器、算法、迭代器。
常用容器速览
| 容器 | 特点 | 典型用法场景 |
|---|---|---|
| vector | 动态数组,随机访问快 | 替代普通数组,大多数序列需求 |
| deque | 双端队列,头尾插入快 | 需要频繁首尾操作 |
| list | 双向链表,插入删除快 | 频繁中间插入删除 |
| set/multiset | 有序集合(红黑树),自动排序去重 | 需要有序、快速查找 |
| map/multimap | 有序键值对 | 字典、配置表 |
| unordered_set/map | 无序哈希集合/映射,平均O(1)查找 | 追求极致速度的查找 |
| stack | 栈(适配器) | 后进先出 |
| queue | 队列(适配器) | 先进先出 |
vector 基本用法示例
#include <vector>
#include <iostream>
std::vector<int> vec;
vec.push_back(10);
vec.push_back(20);
for (int x : vec) { // 范围 for 循环(C++11)
std::cout << x << " ";
}
// 输出:10 20
vec.emplace_back(30); // 更高效的插入(就地构造)
常用算法()
#include <algorithm>
#include <vector>
std::vector<int> v = {3, 1, 4, 1, 5};
std::sort(v.begin(), v.end()); // 排序
auto it = std::find(v.begin(), v.end(), 4); // 查找
std::reverse(v.begin(), v.end()); // 反转
迭代器:容器的“指针”
- begin()/end():正向迭代
- rbegin()/rend():反向迭代
- const_iterator:只读迭代器
三者关系总结
- 内存管理提供了安全高效的资源控制(智能指针是基础)
- 模板让STL成为可能(所有STL容器和算法都是模板)
- STL让你几乎不需要自己实现数据结构和算法,专注业务逻辑
学习路线建议
- 先熟练智能指针(unique_ptr → shared_ptr → weak_ptr)
- 写几个简单函数模板和类模板
- 掌握 vector、string、map、set 这四大常用容器
- 学会用算法(sort、find、max_element 等)
- 再深入 unordered_map、lambda、move 语义等进阶
掌握了这三块,你就已经跨入现代C++的门槛,能写出高效、安全、优雅的代码了!
想继续深入哪个部分(比如智能指针实现原理、STL迭代器失效、模板特化),或者要实战代码练习题,随时告诉我,继续陪你冲!🚀
更多推荐

所有评论(0)