跳到主要内容C++ 零基础入门教程:现代 C++ 核心武器库 STL | 极客日志C++算法
C++ 零基础入门教程:现代 C++ 核心武器库 STL
掌握 C++ STL 标准模板库基础应用,包括 std::vector 动态数组、std::string 字符串处理及 std::map 键值对容器。通过重构成绩系统与实现控制台通讯录项目,演示利用 STL 替代手动内存管理,提升代码安全性与效率。内容涵盖常用操作示例、类型安全说明及性能优化建议,帮助开发者从 C 风格迈向现代 C++。
草莓泡芙52 浏览 C++ 零基础入门教程(第 4 篇)
STL 标准库实战 —— 告别手动内存管理
第一步:为什么需要 STL?
回顾之前的代码,我们用了固定大小的数组:
Student students[10];
但现实中,学生数量是不确定的。如果用 new[] 动态分配,又容易忘记 delete[],导致内存泄漏。
✅ STL 的优势:
- 自动管理内存(无需
new/delete)
- 动态扩容(如
vector)
- 提供丰富算法(排序、查找等)
- 类型安全、异常安全
第二步:std::vector —— 动态数组(必学!)
vector 是可变长数组,会自动增长。
2.1 基本用法
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> numbers;
numbers.push_back(10);
numbers.push_back(20);
numbers.push_back(30);
cout << "第一个数:" << numbers[0] << endl;
cout << "最后一个数:" << numbers.back() << endl;
cout << "当前有 " << numbers.size() << << endl;
( x : numbers) {
cout << x << ;
}
cout << endl;
;
}
" 个元素"
for
int
" "
return
0
第一个数:10 最后一个数:30 当前有 3 个元素 10 20 30
🔑 常用操作:.push_back(value) → 末尾添加 .pop_back() → 删除末尾 .size() → 元素个数 .empty() → 是否为空 [index] 或 .at(index) → 访问(.at 会检查越界)
2.2 vector 存储自定义类型(如 Student)
#include <vector>
#include <string>
using namespace std;
class Student {
public:
string name;
double score;
Student(string n, double s) : name(n), score(s) {}
};
int main() {
vector<Student> students;
students.push_back(Student("Alice", 95));
students.push_back(Student("Bob", 88));
for (const Student& s : students) {
cout << s.name << ": " << s.score << endl;
}
return 0;
}
💡 注意:const Student& 避免不必要的对象复制,提升性能!
第三步:std::string —— 真正的字符串类型
你可能还记得 C 风格字符串(char[])的麻烦:
✅ std::string 的强大功能:
#include <iostream>
#include <string>
using namespace std;
int main() {
string name = "Hello";
name += " C++";
cout << name << endl;
cout << "长度:" << name.length() << endl;
if (name.find("C++") != string::npos) {
cout << "包含 'C++'" << endl;
}
for (char c : name) {
cout << c << "-";
}
cout << endl;
return 0;
}
Hello C++ 长度:8 包含 'C++' H-e-l-l-o- -C-+-+-
🎯 结论:永远优先使用 std::string,不要用 char[]!
第四步:std::map —— 键值对容器(类似 Java HashMap)
map 用于存储 键 → 值 的映射,自动按键排序。
示例:用 map 统计单词出现次数
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<string, int> wordCount;
wordCount["apple"] = 5;
wordCount["banana"] = 3;
wordCount["apple"]++;
for (const auto& pair : wordCount) {
cout << pair.first << ": " << pair.second << endl;
}
if (wordCount.count("orange")) {
cout << "有 orange" << endl;
} else {
cout << "没有 orange" << endl;
}
return 0;
}
apple: 6 banana: 3 没有 orange
🔑 说明:pair.first 是键,pair.second 是值 auto 让编译器自动推导类型(C++11 特性) .count(key) 返回 0 或 1(是否存在)
第五步:升级项目 1 —— 用 vector 重构成绩系统
✅ 改造 GradeSystem 类:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Student {
private:
string name;
double score;
public:
Student(string n, double s) : name(n), score(s) {}
string getName() const { return name; }
double getScore() const { return score; }
void print() const { cout << name << "\t" << score << endl; }
};
class GradeSystem {
private:
vector<Student> students;
public:
void addStudent(const string& name, double score) {
students.push_back(Student(name, score));
}
void printAll() const {
cout << "\n--- 成绩列表 ---\n";
for (const auto& s : students) {
s.print();
}
}
double getAverage() const {
if (students.empty()) return 0;
double sum = 0;
for (const auto& s : students) {
sum += s.getScore();
}
return sum / students.size();
}
Student getTopStudent() const {
if (students.empty()) return Student("无", 0);
Student top = students[0];
for (const auto& s : students) {
if (s.getScore() > top.getScore()) {
top = s;
}
}
return top;
}
};
int main() {
GradeSystem sys;
sys.addStudent("Alice", 95);
sys.addStudent("Bob", 88);
sys.addStudent("Charlie", 92);
sys.addStudent("David", 97);
sys.printAll();
cout << "\n平均分:" << sys.getAverage() << endl;
cout << "最高分:";
sys.getTopStudent().print();
return 0;
}
g++ grade_system_stl.cpp -o grade ./grade
🎉 现在系统可以处理任意数量学生,且内存自动管理!
第六步:实战项目 2 —— 控制台通讯录
我们将综合使用 vector + string + map(可选),实现:
- 添加联系人(姓名 + 电话)
- 查找联系人
- 列出所有联系人
✅ 方案选择:
- 用
vector<Contact> 存储(适合遍历)
- 或用
map<string, string>(姓名 → 电话,适合快速查找)
我们采用 vector + 线性查找(简单清晰):
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Contact {
public:
string name;
string phone;
Contact(string n, string p) : name(n), phone(p) {}
};
class ContactBook {
private:
vector<Contact> contacts;
public:
void addContact(const string& name, const string& phone) {
contacts.push_back(Contact(name, phone));
cout << "已添加 " << name << endl;
}
void findContact(const string& name) const {
bool found = false;
for (const auto& c : contacts) {
if (c.name == name) {
cout << "找到:" << c.name << " - " << c.phone << endl;
found = true;
}
}
if (!found) {
cout << "未找到 " << name << endl;
}
}
void listAll() const {
if (contacts.empty()) {
cout << "通讯录为空" << endl;
return;
}
cout << "\n--- 通讯录 ---\n";
for (const auto& c : contacts) {
cout << c.name << "\t" << c.phone << endl;
}
}
};
int main() {
ContactBook book;
int choice;
string name, phone;
while (true) {
cout << "\n1. 添加联系人\n2. 查找联系人\n3. 列出所有\n0. 退出\n请选择:";
cin >> choice;
if (choice == 0) break;
switch (choice) {
case 1:
cout << "姓名:";
cin >> name;
cout << "电话:";
cin >> phone;
book.addContact(name, phone);
break;
case 2:
cout << "查找姓名:";
cin >> name;
book.findContact(name);
break;
case 3:
book.listAll();
break;
default:
cout << "无效选项" << endl;
}
}
cout << "再见!" << endl;
return 0;
}
g++ contact_book.cpp -o contact ./contact
🎮 你可以添加、查找、列出联系人,完全由 STL 驱动!
📌 本篇小结:你已掌握
| 容器 | 用途 | 对比 Java |
|---|
vector<T> | 动态数组 | ≈ ArrayList<T> |
string | 字符串 | ≈ String(但更高效) |
map<K,V> | 有序键值对 | ≈ TreeMap<K,V> |
✅ 你已具备:使用 STL 编写安全、高效的 C++ 代码。用 vector 替代原始数组构建小型数据管理系统。
✅ 下一步建议
- 尝试优化通讯录:用
map<string, string> 实现 O(log n) 查找
- 预习:什么是'智能指针'?如何管理堆对象?
- 思考:如果 Contact 很大,如何避免
push_back 时的拷贝开销?
→ 答案:移动语义(第 5 篇)
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- Gemini 图片去水印
基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
- HTML转Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online