C++入门知识大全(二)

简介: 教程来源 https://app-aakcgtuh1ywx.appmiaoda.com 本教程系统讲解C++核心知识:涵盖数组/字符串操作、函数重载与lambda、类与继承、STL容器算法、智能指针内存管理,以及C++11/14/17/20现代特性,并通过学生管理系统实战巩固所学,助力初学者扎实掌握面向对象编程与标准库应用。

五、数组与字符串

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

相关文章
|
2天前
|
人工智能 JSON 机器人
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
本文带你零成本玩转OpenClaw:学生认证白嫖6个月阿里云服务器,手把手配置飞书机器人、接入免费/高性价比AI模型(NVIDIA/通义),并打造微信公众号“全自动分身”——实时抓热榜、AI选题拆解、一键发布草稿,5分钟完成热点→文章全流程!
10251 35
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
|
14天前
|
人工智能 安全 Linux
【OpenClaw保姆级图文教程】阿里云/本地部署集成模型Ollama/Qwen3.5/百炼 API 步骤流程及避坑指南
2026年,AI代理工具的部署逻辑已从“单一云端依赖”转向“云端+本地双轨模式”。OpenClaw(曾用名Clawdbot)作为开源AI代理框架,既支持对接阿里云百炼等云端免费API,也能通过Ollama部署本地大模型,完美解决两类核心需求:一是担心云端API泄露核心数据的隐私安全诉求;二是频繁调用导致token消耗过高的成本控制需求。
5938 14
|
22天前
|
人工智能 JavaScript Ubuntu
5分钟上手龙虾AI!OpenClaw部署(阿里云+本地)+ 免费多模型配置保姆级教程(MiniMax、Claude、阿里云百炼)
OpenClaw(昵称“龙虾AI”)作为2026年热门的开源个人AI助手,由PSPDFKit创始人Peter Steinberger开发,核心优势在于“真正执行任务”——不仅能聊天互动,还能自动处理邮件、管理日程、订机票、写代码等,且所有数据本地处理,隐私完全可控。它支持接入MiniMax、Claude、GPT等多类大模型,兼容微信、Telegram、飞书等主流聊天工具,搭配100+可扩展技能,成为兼顾实用性与隐私性的AI工具首选。
23212 120
|
8天前
|
人工智能 JavaScript API
解放双手!OpenClaw Agent Browser全攻略(阿里云+本地部署+免费API+网页自动化场景落地)
“让AI聊聊天、写代码不难,难的是让它自己打开网页、填表单、查数据”——2026年,无数OpenClaw用户被这个痛点困扰。参考文章直击核心:当AI只能“纸上谈兵”,无法实际操控浏览器,就永远成不了真正的“数字员工”。而Agent Browser技能的出现,彻底打破了这一壁垒——它给OpenClaw装上“上网的手和眼睛”,让AI能像真人一样打开网页、点击按钮、填写表单、提取数据,24小时不间断完成网页自动化任务。
1956 4

热门文章

最新文章