C++ 零基础入门教程:现代 C++ 核心武器库 STL
掌握 C++ STL 标准模板库基础应用,包括 std::vector 动态数组、std::string 字符串处理及 std::map 键值对容器。通过重构成绩系统与实现控制台通讯录项目,演示利用 STL 替代手动内存管理,提升代码安全性与效率。内容涵盖常用操作示例、类型安全说明及性能优化建议,帮助开发者从 C 风格迈向现代 C++。

掌握 C++ STL 标准模板库基础应用,包括 std::vector 动态数组、std::string 字符串处理及 std::map 键值对容器。通过重构成绩系统与实现控制台通讯录项目,演示利用 STL 替代手动内存管理,提升代码安全性与效率。内容涵盖常用操作示例、类型安全说明及性能优化建议,帮助开发者从 C 风格迈向现代 C++。

回顾之前的代码,我们用了固定大小的数组:
Student students[10]; // 最多 10 人
但现实中,学生数量是不确定的。如果用 new[] 动态分配,又容易忘记 delete[],导致内存泄漏。
new/delete)vector)std::vector —— 动态数组(必学!)vector 是可变长数组,会自动增长。
#include <iostream>
#include <vector>
// 必须包含
using namespace std;
int main() {
// 创建空 vector
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;
// 遍历(C++11 范围 for 循环)
for (int x : numbers) {
cout << x << " ";
}
cout << endl;
return 0;
}
✅ 输出:
第一个数:10 最后一个数:30 当前有 3 个元素 10 20 30
🔑 常用操作:
.push_back(value)→ 末尾添加.pop_back()→ 删除末尾.size()→ 元素个数.empty()→ 是否为空[index]或.at(index)→ 访问(.at会检查越界)
#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; // Hello C++
cout << "长度:" << name.length() << endl; // 8
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 用于存储 键 → 值 的映射,自动按键排序。
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<string, int> wordCount;
wordCount["apple"] = 5;
wordCount["banana"] = 3;
wordCount["apple"]++; // 变成 6
// 遍历 map
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(是否存在)
我们将移除 MAX 限制,支持任意数量学生。
GradeSystem 类:// grade_system_stl.cpp
#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; // ← 关键:用 vector 替代数组
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
🎉 现在系统可以处理任意数量学生,且内存自动管理!
我们将综合使用 vector + string + map(可选),实现:
vector<Contact> 存储(适合遍历)map<string, string>(姓名 → 电话,适合快速查找)我们采用 vector + 线性查找(简单清晰):
// contact_book.cpp
#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) 查找push_back 时的拷贝开销?
→ 答案:移动语义(第 5 篇)
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online