五、数组与字符串
5.1 数组
#include <iostream>
#include <array> // C++11 std::array
int main() {
// ========== C风格数组 ==========
int arr1[5]; // 声明,未初始化
int arr2[5] = {1, 2, 3, 4, 5}; // 完整初始化
int arr3[] = {1, 2, 3, 4, 5}; // 自动推断大小
int arr4[5] = {1, 2}; // 部分初始化,其余为0
// 访问数组元素
arr2[0] = 10;
std::cout << "arr2[0] = " << arr2[0] << std::endl;
// 遍历数组
std::cout << "数组元素:";
for (int i = 0; i < 5; i++) {
std::cout << arr2[i] << " ";
}
std::cout << std::endl;
// 计算数组长度
int len = sizeof(arr2) / sizeof(arr2[0]);
std::cout << "数组长度:" << len << std::endl;
// ========== std::array(C++11) ==========
std::array<int, 5> arr5 = {1, 2, 3, 4, 5};
// 访问元素
std::cout << "arr5[2] = " << arr5[2] << std::endl;
std::cout << "arr5.at(2) = " << arr5.at(2) << std::endl; // 边界检查
std::cout << "arr5.front() = " << arr5.front() << std::endl; // 第一个元素
std::cout << "arr5.back() = " << arr5.back() << std::endl; // 最后一个元素
// 遍历std::array
for (int x : arr5) {
std::cout << x << " ";
}
std::cout << std::endl;
// 获取大小
std::cout << "arr5大小:" << arr5.size() << std::endl;
std::cout << "arr5是否为空:" << arr5.empty() << std::endl;
// ========== 二维数组 ==========
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
std::cout << "matrix[1][2] = " << matrix[1][2] << std::endl; // 7
// 遍历二维数组
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
std::cout << matrix[i][j] << "\t";
}
std::cout << std::endl;
}
return 0;
}
5.2 字符串
#include <iostream>
#include <string>
#include <cstring> // C风格字符串函数
int main() {
// ========== C风格字符串 ==========
char str1[] = "Hello"; // 自动添加\0
char str2[] = {'H', 'e', 'l', 'l', 'o', '\0'};
char str3[20] = "Hello";
std::cout << "str1: " << str1 << std::endl;
std::cout << "str2: " << str2 << std::endl;
// C字符串函数
char str4[20];
strcpy(str4, "Hello"); // 复制
strcat(str4, " World"); // 连接
int cmp = strcmp("apple", "banana"); // 比较
size_t len = strlen(str4); // 长度
// ========== std::string(C++标准字符串) ==========
std::string s1 = "Hello";
std::string s2("World");
std::string s3 = s1 + " " + s2; // 字符串连接
std::cout << "s3: " << s3 << std::endl;
// 常用操作
std::cout << "长度:" << s3.length() << std::endl;
std::cout << "大小:" << s3.size() << std::endl;
std::cout << "是否为空:" << s3.empty() << std::endl;
// 访问字符
std::cout << "第一个字符:" << s3[0] << std::endl;
std::cout << "最后一个字符:" << s3.back() << std::endl;
// 查找
size_t pos = s3.find("World");
if (pos != std::string::npos) {
std::cout << "找到'World',位置:" << pos << std::endl;
}
// 子串
std::string sub = s3.substr(6, 5); // 从位置6开始取5个字符
std::cout << "子串:" << sub << std::endl;
// 插入和删除
s3.insert(5, ",");
std::cout << "插入后:" << s3 << std::endl;
s3.erase(5, 1);
std::cout << "删除后:" << s3 << std::endl;
// 替换
s3.replace(6, 5, "C++");
std::cout << "替换后:" << s3 << std::endl;
// 追加
s3.append("!");
s3 += "!";
// 输入
std::string input;
std::cout << "请输入字符串:";
std::cin >> input;
std::cout << "输入:" << input << std::endl;
// 读取整行
std::string line;
std::cin.ignore();
std::getline(std::cin, line);
std::cout << "整行:" << line << std::endl;
// 转换为C风格字符串
const char* cstr = s3.c_str();
return 0;
}
六、函数
6.1 函数定义与调用
#include <iostream>
#include <vector>
// ========== 函数声明 ==========
int add(int a, int b);
void printMessage(const std::string& msg);
int factorial(int n);
void swap(int& a, int& b); // 引用传递
// ========== 函数重载 ==========
int max(int a, int b) {
return (a > b) ? a : b;
}
double max(double a, double b) {
return (a > b) ? a : b;
}
int max(int a, int b, int c) {
return max(max(a, b), c);
}
// ========== 默认参数 ==========
void greet(const std::string& name, const std::string& greeting = "你好") {
std::cout << greeting << "," << name << std::endl;
}
// ========== 内联函数 ==========
inline int square(int x) {
return x * x;
}
// ========== constexpr函数(编译时计算) ==========
constexpr int factorial_constexpr(int n) {
return (n <= 1) ? 1 : n * factorial_constexpr(n - 1);
}
// ========== 返回多个值(使用pair/tuple) ==========
#include <utility>
#include <tuple>
std::pair<int, int> get_min_max(const std::vector<int>& vec) {
int min = vec[0], max = vec[0];
for (int v : vec) {
if (v < min) min = v;
if (v > max) max = v;
}
return {min, max};
}
std::tuple<int, int, double> get_stats(const std::vector<int>& vec) {
int min = vec[0], max = vec[0];
double sum = 0;
for (int v : vec) {
if (v < min) min = v;
if (v > max) max = v;
sum += v;
}
return {min, max, sum / vec.size()};
}
// ========== lambda表达式(C++11) ==========
void lambda_demo() {
// 基本lambda
auto add = [](int a, int b) { return a + b; };
std::cout << "lambda add: " << add(3, 5) << std::endl;
// 捕获外部变量
int factor = 10;
auto multiply = [factor](int x) { return x * factor; };
std::cout << "multiply: " << multiply(5) << std::endl;
// 引用捕获
int counter = 0;
auto increment = [&counter]() { counter++; };
increment();
std::cout << "counter: " << counter << std::endl;
// 可变lambda
auto mutable_lambda = [counter]() mutable {
return ++counter;
};
std::cout << "mutable: " << mutable_lambda() << std::endl;
// 泛型lambda(C++14)
auto generic = [](auto a, auto b) { return a + b; };
std::cout << "generic: " << generic(3, 5) << std::endl;
std::cout << "generic: " << generic(3.14, 2.86) << std::endl;
}
int main() {
// 函数调用
int result = add(5, 3);
std::cout << "5 + 3 = " << result << std::endl;
printMessage("Hello, C++!");
int fact = factorial(5);
std::cout << "5! = " << fact << std::endl;
int x = 10, y = 20;
swap(x, y);
std::cout << "swap后:x=" << x << ", y=" << y << std::endl;
// 函数重载
std::cout << "max(10, 20) = " << max(10, 20) << std::endl;
std::cout << "max(3.14, 2.71) = " << max(3.14, 2.71) << std::endl;
std::cout << "max(10, 20, 15) = " << max(10, 20, 15) << std::endl;
// 默认参数
greet("张三");
greet("李四", "早上好");
// 内联函数
std::cout << "square(5) = " << square(5) << std::endl;
// constexpr
constexpr int fact5 = factorial_constexpr(5);
std::cout << "constexpr 5! = " << fact5 << std::endl;
// 返回多个值
std::vector<int> numbers = {3, 7, 1, 9, 4, 2, 8, 5, 6};
auto [min, max] = get_min_max(numbers);
std::cout << "min=" << min << ", max=" << max << std::endl;
auto [min2, max2, avg] = get_stats(numbers);
std::cout << "min=" << min2 << ", max=" << max2 << ", avg=" << avg << std::endl;
// lambda表达式
lambda_demo();
return 0;
}
// ========== 函数定义 ==========
int add(int a, int b) {
return a + b;
}
void printMessage(const std::string& msg) {
std::cout << msg << std::endl;
}
int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
void swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
七、面向对象编程
7.1 类与对象
#include <iostream>
#include <string>
#include <vector>
// ========== 类定义 ==========
class Student {
private:
int id;
std::string name;
int age;
double score;
static int studentCount; // 静态成员变量
public:
// ========== 构造函数 ==========
// 默认构造函数
Student() : id(0), name(""), age(0), score(0.0) {
studentCount++;
}
// 参数化构造函数
Student(int id, const std::string& name, int age, double score)
: id(id), name(name), age(age), score(score) {
studentCount++;
}
// 委托构造函数(C++11)
Student(int id) : Student(id, "", 0, 0.0) {}
// ========== 拷贝构造函数 ==========
Student(const Student& other)
: id(other.id), name(other.name), age(other.age), score(other.score) {
studentCount++;
std::cout << "拷贝构造函数" << std::endl;
}
// ========== 移动构造函数(C++11) ==========
Student(Student&& other) noexcept
: id(other.id), name(std::move(other.name)), age(other.age), score(other.score) {
other.id = 0;
other.age = 0;
other.score = 0;
studentCount++;
std::cout << "移动构造函数" << std::endl;
}
// ========== 析构函数 ==========
~Student() {
studentCount--;
std::cout << "析构函数: " << name << std::endl;
}
// ========== 赋值运算符 ==========
Student& operator=(const Student& other) {
if (this != &other) {
id = other.id;
name = other.name;
age = other.age;
score = other.score;
}
return *this;
}
// ========== 移动赋值运算符 ==========
Student& operator=(Student&& other) noexcept {
if (this != &other) {
id = other.id;
name = std::move(other.name);
age = other.age;
score = other.score;
other.id = 0;
other.age = 0;
other.score = 0;
}
return *this;
}
// ========== Getter和Setter ==========
int getId() const { return id; }
void setId(int id) { this->id = id; }
std::string getName() const { return name; }
void setName(const std::string& name) { this->name = name; }
int getAge() const { return age; }
void setAge(int age) {
if (age >= 0 && age <= 150) {
this->age = age;
}
}
double getScore() const { return score; }
void setScore(double score) { this->score = score; }
// ========== 静态成员函数 ==========
static int getStudentCount() { return studentCount; }
// ========== 成员函数 ==========
void display() const {
std::cout << "学号:" << id
<< ",姓名:" << name
<< ",年龄:" << age
<< ",成绩:" << score << std::endl;
}
bool isPass() const {
return score >= 60.0;
}
// ========== const成员函数 ==========
void info() const {
std::cout << name << " (ID: " << id << ")" << std::endl;
}
// ========== 友元函数 ==========
friend std::ostream& operator<<(std::ostream& os, const Student& s);
};
// 静态成员变量定义
int Student::studentCount = 0;
// 友元函数定义
std::ostream& operator<<(std::ostream& os, const Student& s) {
os << "Student{id=" << s.id << ", name=" << s.name
<< ", age=" << s.age << ", score=" << s.score << "}";
return os;
}
// ========== 使用类 ==========
int main() {
// 创建对象
Student s1; // 默认构造
Student s2(1001, "张三", 20, 85.5); // 参数化构造
Student s3(1002); // 委托构造
s1.setId(1003);
s1.setName("李四");
s1.setAge(21);
s1.setScore(92.0);
// 访问成员
s1.display();
s2.display();
s3.display();
std::cout << "学生总数:" << Student::getStudentCount() << std::endl;
// 拷贝构造
Student s4 = s2;
s4.display();
// 赋值
Student s5;
s5 = s2;
s5.display();
// 移动语义
Student s6 = std::move(s2);
s6.display();
// 友元函数
std::cout << s1 << std::endl;
// const对象
const Student s7(1004, "王五", 22, 78.5);
s7.info(); // 只能调用const成员函数
return 0;
}
7.2 继承与多态
#include <iostream>
#include <string>
#include <vector>
#include <memory>
// ========== 基类 ==========
class Animal {
protected:
std::string name;
int age;
public:
Animal(const std::string& name, int age) : name(name), age(age) {
std::cout << "Animal构造函数" << std::endl;
}
// 虚析构函数(重要!)
virtual ~Animal() {
std::cout << "Animal析构函数" << std::endl;
}
// 虚函数(支持多态)
virtual void speak() const {
std::cout << name << "发出声音" << std::endl;
}
// 纯虚函数(抽象类)
virtual void move() const = 0;
// 普通成员函数
void info() const {
std::cout << "名字:" << name << ",年龄:" << age << std::endl;
}
std::string getName() const { return name; }
int getAge() const { return age; }
};
// ========== 派生类 ==========
class Dog : public Animal {
private:
std::string breed; // 品种
public:
Dog(const std::string& name, int age, const std::string& breed)
: Animal(name, age), breed(breed) {
std::cout << "Dog构造函数" << std::endl;
}
~Dog() override {
std::cout << "Dog析构函数" << std::endl;
}
// 重写虚函数
void speak() const override {
std::cout << name << "汪汪叫" << std::endl;
}
void move() const override {
std::cout << name << "跑动" << std::endl;
}
// 派生类特有方法
void wagTail() const {
std::cout << name << "摇尾巴" << std::endl;
}
std::string getBreed() const { return breed; }
};
class Cat : public Animal {
public:
Cat(const std::string& name, int age) : Animal(name, age) {
std::cout << "Cat构造函数" << std::endl;
}
~Cat() override {
std::cout << "Cat析构函数" << std::endl;
}
void speak() const override {
std::cout << name << "喵喵叫" << std::endl;
}
void move() const override {
std::cout << name << "跳跃" << std::endl;
}
void climb() const {
std::cout << name << "爬树" << std::endl;
}
};
// ========== 多重继承(谨慎使用) ==========
class Flyable {
public:
virtual void fly() const = 0;
virtual ~Flyable() = default;
};
class Bird : public Animal, public Flyable {
public:
Bird(const std::string& name, int age) : Animal(name, age) {}
void speak() const override {
std::cout << name << "叽叽喳喳" << std::endl;
}
void move() const override {
std::cout << name << "飞行" << std::endl;
}
void fly() const override {
std::cout << name << "展翅高飞" << std::endl;
}
};
// ========== 抽象基类 ==========
class Shape {
public:
virtual double area() const = 0;
virtual double perimeter() const = 0;
virtual ~Shape() = default;
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
double area() const override {
return 3.14159 * radius * radius;
}
double perimeter() const override {
return 2 * 3.14159 * radius;
}
};
class Rectangle : public Shape {
private:
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double area() const override {
return width * height;
}
double perimeter() const override {
return 2 * (width + height);
}
};
// ========== 多态使用 ==========
void makeSound(const Animal& animal) {
animal.speak();
}
void makeMove(const Animal& animal) {
animal.move();
}
int main() {
// ========== 基本继承 ==========
Dog dog("旺财", 3, "金毛");
Cat cat("咪咪", 2);
dog.speak();
cat.speak();
dog.wagTail();
cat.climb();
// ========== 多态 ==========
Animal* ptr1 = new Dog("来福", 2, "哈士奇");
Animal* ptr2 = new Cat("小花", 1);
ptr1->speak(); // 调用Dog的speak
ptr2->speak(); // 调用Cat的speak
delete ptr1;
delete ptr2;
// ========== 引用多态 ==========
makeSound(dog);
makeSound(cat);
// ========== 容器存储多态对象 ==========
std::vector<std::unique_ptr<Animal>> animals;
animals.push_back(std::make_unique<Dog>("旺财", 3, "金毛"));
animals.push_back(std::make_unique<Cat>("咪咪", 2));
animals.push_back(std::make_unique<Bird>("小鸟", 1));
for (const auto& animal : animals) {
animal->speak();
animal->move();
}
// ========== 抽象类 ==========
std::vector<std::unique_ptr<Shape>> shapes;
shapes.push_back(std::make_unique<Circle>(5.0));
shapes.push_back(std::make_unique<Rectangle>(4.0, 6.0));
for (const auto& shape : shapes) {
std::cout << "面积:" << shape->area()
<< ",周长:" << shape->perimeter() << std::endl;
}
// ========== 类型转换 ==========
Animal* animal = new Dog("阿黄", 2, "柴犬");
// dynamic_cast(运行时类型检查)
Dog* dogPtr = dynamic_cast<Dog*>(animal);
if (dogPtr) {
dogPtr->wagTail();
}
// static_cast(编译时转换,不安全)
// Dog* dogPtr2 = static_cast<Dog*>(animal);
delete animal;
return 0;
}
八、标准模板库(STL)
8.1 容器
#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <stack>
#include <queue>
void container_demo() {
// ========== vector(动态数组) ==========
std::vector<int> vec = {1, 2, 3, 4, 5};
// 添加元素
vec.push_back(6);
vec.insert(vec.begin() + 2, 10); // 在位置2插入10
// 访问元素
std::cout << "vec[2] = " << vec[2] << std::endl;
std::cout << "vec.at(2) = " << vec.at(2) << std::endl;
std::cout << "vec.front() = " << vec.front() << std::endl;
std::cout << "vec.back() = " << vec.back() << std::endl;
// 遍历
std::cout << "vector: ";
for (int x : vec) {
std::cout << x << " ";
}
std::cout << std::endl;
// 删除元素
vec.pop_back();
vec.erase(vec.begin() + 2);
// 容量
std::cout << "size: " << vec.size() << std::endl;
std::cout << "capacity: " << vec.capacity() << std::endl;
// ========== list(双向链表) ==========
std::list<int> lst = {1, 2, 3, 4, 5};
lst.push_front(0);
lst.push_back(6);
lst.pop_front();
lst.pop_back();
std::cout << "list: ";
for (int x : lst) {
std::cout << x << " ";
}
std::cout << std::endl;
// ========== deque(双端队列) ==========
std::deque<int> dq = {1, 2, 3};
dq.push_front(0);
dq.push_back(4);
// ========== set(有序集合) ==========
std::set<int> set = {3, 1, 4, 1, 5, 9, 2};
set.insert(6);
set.erase(4);
std::cout << "set: ";
for (int x : set) {
std::cout << x << " ";
}
std::cout << std::endl;
// 查找
auto it = set.find(5);
if (it != set.end()) {
std::cout << "找到5" << std::endl;
}
// ========== multiset(允许重复) ==========
std::multiset<int> mset = {1, 2, 2, 3, 3, 3};
std::cout << "multiset中2的个数:" << mset.count(2) << std::endl;
// ========== map(有序映射) ==========
std::map<std::string, int> map;
map["苹果"] = 5;
map["香蕉"] = 3;
map["橙子"] = 4;
map.insert({"葡萄", 6});
std::cout << "map: ";
for (const auto& [key, value] : map) {
std::cout << key << ":" << value << " ";
}
std::cout << std::endl;
// 查找
auto mit = map.find("香蕉");
if (mit != map.end()) {
std::cout << "香蕉价格:" << mit->second << std::endl;
}
// ========== unordered_set(哈希集合) ==========
std::unordered_set<int> uset = {3, 1, 4, 1, 5};
uset.insert(2);
// ========== unordered_map(哈希映射) ==========
std::unordered_map<std::string, int> umap;
umap["苹果"] = 5;
umap["香蕉"] = 3;
// ========== stack(栈) ==========
std::stack<int> stk;
stk.push(1);
stk.push(2);
stk.push(3);
std::cout << "栈顶:" << stk.top() << std::endl;
stk.pop();
// ========== queue(队列) ==========
std::queue<int> que;
que.push(1);
que.push(2);
que.push(3);
std::cout << "队首:" << que.front() << std::endl;
que.pop();
// ========== priority_queue(优先队列) ==========
std::priority_queue<int> pq; // 最大堆
pq.push(3);
pq.push(1);
pq.push(4);
std::cout << "最大堆顶:" << pq.top() << std::endl;
// 最小堆
std::priority_queue<int, std::vector<int>, std::greater<int>> min_pq;
min_pq.push(3);
min_pq.push(1);
min_pq.push(4);
std::cout << "最小堆顶:" << min_pq.top() << std::endl;
}
8.2 迭代器与算法
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <iterator>
void algorithm_demo() {
std::vector<int> vec = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};
// ========== 迭代器 ==========
// 正向迭代器
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 反向迭代器
for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// ========== 排序 ==========
std::sort(vec.begin(), vec.end());
std::cout << "排序后:";
for (int x : vec) std::cout << x << " ";
std::cout << std::endl;
// 降序排序
std::sort(vec.begin(), vec.end(), std::greater<int>());
std::cout << "降序:";
for (int x : vec) std::cout << x << " ";
std::cout << std::endl;
// ========== 查找 ==========
auto it = std::find(vec.begin(), vec.end(), 5);
if (it != vec.end()) {
std::cout << "找到5,位置:" << std::distance(vec.begin(), it) << std::endl;
}
// ========== 计数 ==========
int count = std::count(vec.begin(), vec.end(), 5);
std::cout << "5的个数:" << count << std::endl;
// ========== 最大值/最小值 ==========
auto min_it = std::min_element(vec.begin(), vec.end());
auto max_it = std::max_element(vec.begin(), vec.end());
std::cout << "最小值:" << *min_it << ",最大值:" << *max_it << std::endl;
// ========== 复制 ==========
std::vector<int> dest(vec.size());
std::copy(vec.begin(), vec.end(), dest.begin());
// ========== 去重 ==========
std::sort(vec.begin(), vec.end());
auto last = std::unique(vec.begin(), vec.end());
vec.erase(last, vec.end());
std::cout << "去重后:";
for (int x : vec) std::cout << x << " ";
std::cout << std::endl;
// ========== 反转 ==========
std::reverse(vec.begin(), vec.end());
std::cout << "反转后:";
for (int x : vec) std::cout << x << " ";
std::cout << std::endl;
// ========== 求和 ==========
int sum = std::accumulate(vec.begin(), vec.end(), 0);
std::cout << "总和:" << sum << std::endl;
// ========== 变换 ==========
std::vector<int> squares(vec.size());
std::transform(vec.begin(), vec.end(), squares.begin(),
[](int x) { return x * x; });
// ========== 条件判断 ==========
bool all_positive = std::all_of(vec.begin(), vec.end(),
[](int x) { return x > 0; });
std::cout << "所有正数:" << (all_positive ? "是" : "否") << std::endl;
// ========== 排列 ==========
std::vector<int> perm = {1, 2, 3};
std::cout << "排列:";
do {
std::cout << perm[0] << perm[1] << perm[2] << " ";
} while (std::next_permutation(perm.begin(), perm.end()));
std::cout << std::endl;
// ========== 集合操作 ==========
std::vector<int> set1 = {1, 2, 3, 4, 5};
std::vector<int> set2 = {3, 4, 5, 6, 7};
std::vector<int> intersection;
std::vector<int> union_set;
std::vector<int> difference;
std::set_intersection(set1.begin(), set1.end(),
set2.begin(), set2.end(),
std::back_inserter(intersection));
std::set_union(set1.begin(), set1.end(),
set2.begin(), set2.end(),
std::back_inserter(union_set));
std::set_difference(set1.begin(), set1.end(),
set2.begin(), set2.end(),
std::back_inserter(difference));
}
九、内存管理
9.1 动态内存分配
#include <iostream>
#include <memory>
#include <vector>
// ========== 传统new/delete ==========
void traditional_memory() {
// 单个对象
int* p = new int(10);
std::cout << "*p = " << *p << std::endl;
delete p;
// 数组
int* arr = new int[10];
for (int i = 0; i < 10; i++) {
arr[i] = i;
}
delete[] arr;
}
// ========== 智能指针 ==========
// unique_ptr(独占所有权)
void unique_ptr_demo() {
std::unique_ptr<int> p1 = std::make_unique<int>(10);
std::cout << "*p1 = " << *p1 << std::endl;
// 转移所有权
std::unique_ptr<int> p2 = std::move(p1);
std::cout << "*p2 = " << *p2 << std::endl;
// p1 now empty
// 自定义删除器
auto deleter = [](int* p) {
std::cout << "自定义删除器" << std::endl;
delete p;
};
std::unique_ptr<int, decltype(deleter)> p3(new int(20), deleter);
}
// shared_ptr(共享所有权)
void shared_ptr_demo() {
std::shared_ptr<int> p1 = std::make_shared<int>(10);
std::cout << "引用计数:" << p1.use_count() << std::endl;
{
std::shared_ptr<int> p2 = p1; // 共享所有权
std::cout << "引用计数:" << p1.use_count() << std::endl;
}
std::cout << "引用计数:" << p1.use_count() << std::endl;
}
// weak_ptr(弱引用,解决循环引用)
class Node {
public:
std::shared_ptr<Node> next;
std::weak_ptr<Node> prev; // 使用weak_ptr避免循环引用
~Node() {
std::cout << "Node destroyed" << std::endl;
}
};
void weak_ptr_demo() {
auto node1 = std::make_shared<Node>();
auto node2 = std::make_shared<Node>();
node1->next = node2;
node2->prev = node1;
// 使用weak_ptr
if (auto locked = node2->prev.lock()) {
std::cout << "prev exists" << std::endl;
}
}
// ========== RAII示例 ==========
class FileHandle {
private:
FILE* file;
public:
FileHandle(const char* filename, const char* mode) {
file = fopen(filename, mode);
if (!file) {
throw std::runtime_error("无法打开文件");
}
std::cout << "文件已打开" << std::endl;
}
~FileHandle() {
if (file) {
fclose(file);
std::cout << "文件已关闭" << std::endl;
}
}
// 禁止拷贝
FileHandle(const FileHandle&) = delete;
FileHandle& operator=(const FileHandle&) = delete;
// 移动语义
FileHandle(FileHandle&& other) noexcept : file(other.file) {
other.file = nullptr;
}
void write(const std::string& data) {
if (file) {
fprintf(file, "%s\n", data.c_str());
}
}
};
void raii_demo() {
try {
FileHandle fh("test.txt", "w");
fh.write("Hello, RAII!");
// 自动关闭文件
} catch (const std::exception& e) {
std::cout << "错误:" << e.what() << std::endl;
}
}
int main() {
traditional_memory();
unique_ptr_demo();
shared_ptr_demo();
weak_ptr_demo();
raii_demo();
return 0;
}
十、现代C++特性(C++11/14/17/20)
10.1 C++11核心特性
#include <iostream>
#include <vector>
#include <memory>
#include <chrono>
#include <thread>
#include <mutex>
#include <condition_variable>
// ========== 自动类型推导 ==========
void auto_demo() {
auto x = 10; // int
auto y = 3.14; // double
auto z = "hello"; // const char*
std::vector<int> vec = {1, 2, 3};
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
}
// ========== 范围for循环 ==========
void range_for_demo() {
std::vector<int> vec = {1, 2, 3, 4, 5};
for (int x : vec) {
std::cout << x << " ";
}
std::cout << std::endl;
for (int& x : vec) {
x *= 2;
}
}
// ========== nullptr ==========
void null_ptr_demo() {
int* p = nullptr; // 替代NULL
if (p == nullptr) {
std::cout << "空指针" << std::endl;
}
}
// ========== 初始化列表 ==========
#include <initializer_list>
class MyVector {
private:
std::vector<int> data;
public:
MyVector(std::initializer_list<int> list) : data(list) {}
void print() const {
for (int x : data) {
std::cout << x << " ";
}
std::cout << std::endl;
}
};
void initializer_list_demo() {
MyVector v = {1, 2, 3, 4, 5};
v.print();
}
// ========== 右值引用与移动语义 ==========
class BigData {
private:
int* data;
size_t size;
public:
BigData(size_t n) : size(n) {
data = new int[n];
std::cout << "构造函数" << std::endl;
}
~BigData() {
delete[] data;
std::cout << "析构函数" << std::endl;
}
// 拷贝构造函数
BigData(const BigData& other) : size(other.size) {
data = new int[size];
std::copy(other.data, other.data + size, data);
std::cout << "拷贝构造" << std::endl;
}
// 移动构造函数
BigData(BigData&& other) noexcept : data(other.data), size(other.size) {
other.data = nullptr;
other.size = 0;
std::cout << "移动构造" << std::endl;
}
// 拷贝赋值
BigData& operator=(const BigData& other) {
if (this != &other) {
delete[] data;
size = other.size;
data = new int[size];
std::copy(other.data, other.data + size, data);
std::cout << "拷贝赋值" << std::endl;
}
return *this;
}
// 移动赋值
BigData& operator=(BigData&& other) noexcept {
if (this != &other) {
delete[] data;
data = other.data;
size = other.size;
other.data = nullptr;
other.size = 0;
std::cout << "移动赋值" << std::endl;
}
return *this;
}
};
BigData createBigData() {
BigData bd(1000);
return bd; // 返回时使用移动语义
}
void move_semantics_demo() {
BigData bd1(100);
BigData bd2 = std::move(bd1); // 移动构造
BigData bd3(200);
bd3 = std::move(bd2); // 移动赋值
}
// ========== 多线程支持 ==========
std::mutex mtx;
int counter = 0;
void increment() {
for (int i = 0; i < 1000000; i++) {
std::lock_guard<std::mutex> lock(mtx);
counter++;
}
}
void thread_demo() {
std::thread t1(increment);
std::thread t2(increment);
t1.join();
t2.join();
std::cout << "counter: " << counter << std::endl;
}
// ========== 正则表达式 ==========
#include <regex>
void regex_demo() {
std::string text = "The quick brown fox jumps over the lazy dog";
std::regex word_regex("\\b\\w+\\b");
auto words_begin = std::sregex_iterator(text.begin(), text.end(), word_regex);
auto words_end = std::sregex_iterator();
std::cout << "单词列表:";
for (auto it = words_begin; it != words_end; ++it) {
std::cout << it->str() << " ";
}
std::cout << std::endl;
// 邮箱验证
std::regex email_regex(R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})");
std::string email = "user@example.com";
if (std::regex_match(email, email_regex)) {
std::cout << "邮箱格式正确" << std::endl;
}
}
10.2 C++14/17/20新特性
#include <iostream>
#include <vector>
#include <optional>
#include <variant>
#include <any>
#include <string_view>
#include <filesystem>
#include <execution>
// ========== C++14特性 ==========
// 泛型lambda
void cpp14_demo() {
auto generic_lambda = [](auto a, auto b) { return a + b; };
std::cout << generic_lambda(3, 5) << std::endl;
std::cout << generic_lambda(3.14, 2.86) << std::endl;
// 返回类型推导
auto add = [](auto a, auto b) -> decltype(a + b) { return a + b; };
// 二进制字面量
int binary = 0b1101; // 13
std::cout << "binary: " << binary << std::endl;
}
// ========== C++17特性 ==========
// 结构化绑定
void structured_binding_demo() {
std::map<std::string, int> map = {
{"apple", 5}, {"banana", 3}};
for (const auto& [key, value] : map) {
std::cout << key << ": " << value << std::endl;
}
std::vector<int> vec = {1, 2, 3, 4, 5};
auto [first, second, third] = std::tuple{1, 2, 3};
}
// if/switch初始化语句
void if_init_demo() {
if (int x = 10; x > 5) {
std::cout << "x = " << x << std::endl;
}
switch (int y = 20; y) {
case 20:
std::cout << "y = 20" << std::endl;
break;
}
}
// std::optional
std::optional<int> find_value(const std::vector<int>& vec, int target) {
for (int v : vec) {
if (v == target) {
return v;
}
}
return std::nullopt;
}
void optional_demo() {
std::vector<int> vec = {1, 2, 3, 4, 5};
if (auto result = find_value(vec, 3)) {
std::cout << "找到:" << *result << std::endl;
} else {
std::cout << "未找到" << std::endl;
}
std::cout << "默认值:" << find_value(vec, 10).value_or(-1) << std::endl;
}
// std::variant
void variant_demo() {
std::variant<int, double, std::string> var;
var = 42;
std::cout << "int: " << std::get<int>(var) << std::endl;
var = 3.14;
std::cout << "double: " << std::get<double>(var) << std::endl;
var = "hello";
std::cout << "string: " << std::get<std::string>(var) << std::endl;
// 访问者模式
std::visit([](auto&& arg) {
std::cout << "visit: " << arg << std::endl;
}, var);
}
// std::any
void any_demo() {
std::any a = 42;
std::cout << "int: " << std::any_cast<int>(a) << std::endl;
a = std::string("hello");
std::cout << "string: " << std::any_cast<std::string>(a) << std::endl;
a = 3.14;
std::cout << "double: " << std::any_cast<double>(a) << std::endl;
}
// string_view(轻量级字符串视图)
void string_view_demo() {
std::string str = "Hello, World!";
std::string_view sv = str;
std::cout << "string_view: " << sv << std::endl;
std::cout << "substr: " << sv.substr(7, 5) << std::endl;
}
// 并行算法(C++17)
void parallel_algorithm_demo() {
std::vector<int> vec(1000000);
for (int i = 0; i < 1000000; i++) {
vec[i] = rand() % 1000000;
}
// 并行排序
std::sort(std::execution::par, vec.begin(), vec.end());
// 并行变换
std::vector<int> result(vec.size());
std::transform(std::execution::par_unseq, vec.begin(), vec.end(),
result.begin(), [](int x) { return x * 2; });
}
// ========== C++20特性 ==========
// 概念(Concepts)
template<typename T>
concept Number = std::is_arithmetic_v<T>;
template<Number T>
T add(T a, T b) {
return a + b;
}
// 范围(Ranges)
#include <ranges>
void ranges_demo() {
std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 筛选偶数,取前5个,乘以2
auto result = vec | std::views::filter([](int x) { return x % 2 == 0; })
| std::views::take(5)
| std::views::transform([](int x) { return x * 2; });
for (int x : result) {
std::cout << x << " ";
}
std::cout << std::endl;
}
// 协程(Coroutines)示例
#include <coroutine>
#include <generator> // C++23
// 文件系统(C++17)
namespace fs = std::filesystem;
void filesystem_demo() {
for (const auto& entry : fs::directory_iterator(".")) {
std::cout << entry.path() << std::endl;
}
}
int main() {
cpp14_demo();
structured_binding_demo();
optional_demo();
variant_demo();
string_view_demo();
ranges_demo();
filesystem_demo();
return 0;
}
十一、实战案例:学生管理系统
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <memory>
#include <fstream>
#include <iomanip>
// ========== 学生类 ==========
class Student {
private:
int id;
std::string name;
int age;
std::map<std::string, double> scores;
public:
Student(int id, const std::string& name, int age)
: id(id), name(name), age(age) {}
int getId() const { return id; }
std::string getName() const { return name; }
int getAge() const { return age; }
void addScore(const std::string& subject, double score) {
scores[subject] = score;
}
double getScore(const std::string& subject) const {
auto it = scores.find(subject);
return (it != scores.end()) ? it->second : 0.0;
}
double getAverage() const {
if (scores.empty()) return 0.0;
double sum = 0.0;
for (const auto& [subject, score] : scores) {
sum += score;
}
return sum / scores.size();
}
void display() const {
std::cout << "学号:" << id << ",姓名:" << name << ",年龄:" << age << std::endl;
std::cout << "成绩:" << std::endl;
for (const auto& [subject, score] : scores) {
std::cout << " " << subject << ": " << std::fixed << std::setprecision(1) << score << std::endl;
}
std::cout << "平均分:" << std::fixed << std::setprecision(2) << getAverage() << std::endl;
std::cout << "------------------------" << std::endl;
}
friend std::ostream& operator<<(std::ostream& os, const Student& s) {
os << s.id << "," << s.name << "," << s.age;
for (const auto& [subject, score] : s.scores) {
os << "," << subject << "," << score;
}
return os;
}
};
// ========== 学生管理系统 ==========
class StudentManager {
private:
std::map<int, std::unique_ptr<Student>> students;
std::vector<std::string> subjects;
public:
void addStudent() {
std::cout << "\n--- 添加学生 ---" << std::endl;
int id;
std::string name;
int age;
std::cout << "学号:";
std::cin >> id;
if (students.find(id) != students.end()) {
std::cout << "学号已存在!" << std::endl;
return;
}
std::cout << "姓名:";
std::cin >> name;
std::cout << "年龄:";
std::cin >> age;
students[id] = std::make_unique<Student>(id, name, age);
std::cout << "学生添加成功!" << std::endl;
}
void addScore() {
std::cout << "\n--- 添加成绩 ---" << std::endl;
int id;
std::cout << "学号:";
std::cin >> id;
auto it = students.find(id);
if (it == students.end()) {
std::cout << "学生不存在!" << std::endl;
return;
}
std::string subject;
double score;
std::cout << "科目:";
std::cin >> subject;
std::cout << "成绩:";
std::cin >> score;
it->second->addScore(subject, score);
// 记录科目
if (std::find(subjects.begin(), subjects.end(), subject) == subjects.end()) {
subjects.push_back(subject);
}
std::cout << "成绩添加成功!" << std::endl;
}
void displayAll() const {
std::cout << "\n--- 学生列表 ---" << std::endl;
if (students.empty()) {
std::cout << "暂无学生数据" << std::endl;
return;
}
for (const auto& [id, student] : students) {
student->display();
}
}
void searchStudent() const {
std::cout << "\n--- 搜索学生 ---" << std::endl;
int id;
std::cout << "学号:";
std::cin >> id;
auto it = students.find(id);
if (it == students.end()) {
std::cout << "学生不存在!" << std::endl;
} else {
it->second->display();
}
}
void deleteStudent() {
std::cout << "\n--- 删除学生 ---" << std::endl;
int id;
std::cout << "学号:";
std::cin >> id;
auto it = students.find(id);
if (it == students.end()) {
std::cout << "学生不存在!" << std::endl;
} else {
students.erase(it);
std::cout << "学生已删除!" << std::endl;
}
}
void showStatistics() const {
std::cout << "\n--- 统计信息 ---" << std::endl;
if (students.empty()) {
std::cout << "暂无学生数据" << std::endl;
return;
}
double total = 0.0;
double maxScore = 0.0;
double minScore = 100.0;
const Student* bestStudent = nullptr;
const Student* worstStudent = nullptr;
for (const auto& [id, student] : students) {
double avg = student->getAverage();
total += avg;
if (avg > maxScore) {
maxScore = avg;
bestStudent = student.get();
}
if (avg < minScore) {
minScore = avg;
worstStudent = student.get();
}
}
double classAvg = total / students.size();
std::cout << "班级人数:" << students.size() << std::endl;
std::cout << "班级平均分:" << std::fixed << std::setprecision(2) << classAvg << std::endl;
if (bestStudent) {
std::cout << "最高分:" << bestStudent->getName() << " ("
<< std::fixed << std::setprecision(2) << maxScore << "分)" << std::endl;
}
if (worstStudent) {
std::cout << "最低分:" << worstStudent->getName() << " ("
<< std::fixed << std::setprecision(2) << minScore << "分)" << std::endl;
}
}
void saveToFile(const std::string& filename) const {
std::ofstream file(filename);
if (!file) {
std::cout << "文件打开失败!" << std::endl;
return;
}
for (const auto& [id, student] : students) {
file << *student << std::endl;
}
std::cout << "数据保存成功!" << std::endl;
}
void run() {
int choice;
do {
std::cout << "\n========================================" << std::endl;
std::cout << " 学生成绩管理系统" << std::endl;
std::cout << "========================================" << std::endl;
std::cout << "1. 添加学生" << std::endl;
std::cout << "2. 添加成绩" << std::endl;
std::cout << "3. 显示所有学生" << std::endl;
std::cout << "4. 搜索学生" << std::endl;
std::cout << "5. 删除学生" << std::endl;
std::cout << "6. 统计信息" << std::endl;
std::cout << "7. 保存数据" << std::endl;
std::cout << "8. 退出系统" << std::endl;
std::cout << "========================================" << std::endl;
std::cout << "请选择操作(1-8):";
std::cin >> choice;
switch (choice) {
case 1: addStudent(); break;
case 2: addScore(); break;
case 3: displayAll(); break;
case 4: searchStudent(); break;
case 5: deleteStudent(); break;
case 6: showStatistics(); break;
case 7: saveToFile("students.txt"); break;
case 8: std::cout << "感谢使用学生成绩管理系统!" << std::endl; break;
default: std::cout << "无效选择,请重新输入" << std::endl;
}
} while (choice != 8);
}
};
int main() {
StudentManager manager;
manager.run();
return 0;
}
知识体系图谱
C++入门知识
├── 基础语法
│ ├── 数据类型与变量
│ ├── 运算符与表达式
│ ├── 控制流(if/switch/循环)
│ └── 函数与重载
├── 面向对象
│ ├── 类与对象
│ ├── 构造函数与析构函数
│ ├── 继承与多态
│ └── 虚函数与抽象类
├── 标准库
│ ├── 容器(vector/list/map/set)
│ ├── 迭代器
│ ├── 算法(排序/查找/变换)
│ └── 字符串(string)
├── 内存管理
│ ├── new/delete
│ ├── 智能指针(unique_ptr/shared_ptr/weak_ptr)
│ └── RAII原则
├── 现代C++特性
│ ├── auto/decltype
│ ├── 范围for循环
│ ├── 移动语义
│ ├── lambda表达式
│ └── 结构化绑定
└── 实战项目
├── 学生管理系统
├── 通讯录
└── 图书管理系统
对于初学者而言,最重要的是理解面向对象思想和掌握标准库的使用。C++的学习曲线较为陡峭,但一旦掌握,你将能够构建高性能、可维护的大型系统。
来源:
https://app-aakcgtuh1ywx.appmiaoda.com