<返回目录     Powered by claude/xia兄

第15课: 现代C++特性

auto关键字(C++11)

#include <iostream>
#include <vector>
#include <map>
using namespace std;

int main() {
    // 自动类型推导
    auto x = 10;           // int
    auto y = 3.14;         // double
    auto str = "Hello";    // const char*

    // 简化复杂类型
    vector<int> vec = {1, 2, 3};
    auto it = vec.begin();  // vector<int>::iterator

    map<string, int> m;
    for (auto pair : m) {   // 简化遍历
        cout << pair.first << ": " << pair.second << endl;
    }

    return 0;
}

智能指针(C++11)

#include <iostream>
#include <memory>
using namespace std;

class Person {
public:
    string name;
    Person(string n) : name(n) {
        cout << "创建Person: " << name << endl;
    }
    ~Person() {
        cout << "销毁Person: " << name << endl;
    }
};

int main() {
    // unique_ptr:独占所有权
    unique_ptr<Person> p1(new Person("张三"));
    // unique_ptr<Person> p2 = p1;  // 错误!不能拷贝
    unique_ptr<Person> p2 = move(p1);  // 可以移动

    // shared_ptr:共享所有权
    shared_ptr<Person> p3 = make_shared<Person>("李四");
    shared_ptr<Person> p4 = p3;  // 引用计数+1
    cout << "引用计数:" << p3.use_count() << endl;

    // weak_ptr:弱引用,不增加引用计数
    weak_ptr<Person> wp = p3;
    cout << "引用计数:" << p3.use_count() << endl;

    return 0;
}  // 自动释放内存

Lambda表达式(C++11)

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    // 基本lambda
    auto add = [](int a, int b) { return a + b; };
    cout << "5 + 3 = " << add(5, 3) << endl;

    // 捕获外部变量
    int x = 10;
    auto print = [x]() { cout << "x = " << x << endl; };
    print();

    // 按引用捕获
    int y = 20;
    auto modify = [&y]() { y = 30; };
    modify();
    cout << "y = " << y << endl;

    // 在算法中使用
    vector<int> vec = {1, 2, 3, 4, 5};
    int count = count_if(vec.begin(), vec.end(), [](int x) { return x > 3; });
    cout << "大于3的元素:" << count << endl;

    // 排序
    sort(vec.begin(), vec.end(), [](int a, int b) { return a > b; });

    return 0;
}

范围for循环(C++11)

#include <iostream>
#include <vector>
#include <map>
using namespace std;

int main() {
    vector<int> vec = {1, 2, 3, 4, 5};

    // 只读遍历
    for (int num : vec) {
        cout << num << " ";
    }
    cout << endl;

    // 修改元素(引用)
    for (int &num : vec) {
        num *= 2;
    }

    // 常量引用(避免拷贝)
    for (const auto &num : vec) {
        cout << num << " ";
    }
    cout << endl;

    // 遍历map
    map<string, int> m = {{"a", 1}, {"b", 2}};
    for (const auto &[key, value] : m) {  // C++17结构化绑定
        cout << key << ": " << value << endl;
    }

    return 0;
}

nullptr(C++11)

#include <iostream>
using namespace std;

void func(int x) {
    cout << "调用int版本" << endl;
}

void func(int *ptr) {
    cout << "调用指针版本" << endl;
}

int main() {
    // func(NULL);     // 歧义!NULL是0
    func(nullptr);     // 明确调用指针版本

    int *ptr = nullptr;
    if (ptr == nullptr) {
        cout << "ptr是空指针" << endl;
    }

    return 0;
}

右值引用与移动语义(C++11)

#include <iostream>
#include <vector>
using namespace std;

class Array {
private:
    int *data;
    int size;

public:
    Array(int s) : size(s) {
        data = new int[size];
        cout << "构造函数" << endl;
    }

    ~Array() {
        delete[] data;
        cout << "析构函数" << endl;
    }

    // 拷贝构造函数
    Array(const Array &other) : size(other.size) {
        data = new int[size];
        copy(other.data, other.data + size, data);
        cout << "拷贝构造函数" << endl;
    }

    // 移动构造函数
    Array(Array &&other) noexcept : data(other.data), size(other.size) {
        other.data = nullptr;
        other.size = 0;
        cout << "移动构造函数" << endl;
    }
};

Array createArray() {
    return Array(10);
}

int main() {
    Array arr1 = createArray();  // 调用移动构造函数

    return 0;
}

constexpr(C++11)

#include <iostream>
using namespace std;

// 编译期常量表达式
constexpr int factorial(int n) {
    return (n <= 1) ? 1 : n * factorial(n - 1);
}

constexpr int square(int x) {
    return x * x;
}

int main() {
    // 编译期计算
    constexpr int result = factorial(5);
    cout << "5! = " << result << endl;

    constexpr int arr[square(3)];  // 数组大小必须是编译期常量
    cout << "数组大小:" << sizeof(arr) / sizeof(int) << endl;

    return 0;
}

结构化绑定(C++17)

#include <iostream>
#include <tuple>
#include <map>
using namespace std;

tuple<int, double, string> getData() {
    return {100, 3.14, "Hello"};
}

int main() {
    // 解包tuple
    auto [num, pi, str] = getData();
    cout << num << ", " << pi << ", " << str << endl;

    // 遍历map
    map<string, int> m = {{"a", 1}, {"b", 2}};
    for (const auto &[key, value] : m) {
        cout << key << ": " << value << endl;
    }

    // 数组
    int arr[] = {1, 2, 3};
    auto [x, y, z] = arr;
    cout << x << ", " << y << ", " << z << endl;

    return 0;
}

std::optional(C++17)

#include <iostream>
#include <optional>
using namespace std;

optional<int> divide(int a, int b) {
    if (b == 0) {
        return nullopt;  // 返回空值
    }
    return a / b;
}

int main() {
    auto result = divide(10, 2);
    if (result.has_value()) {
        cout << "结果:" << result.value() << endl;
    }

    auto result2 = divide(10, 0);
    if (!result2) {
        cout << "除数为0" << endl;
    }

    // 提供默认值
    cout << "结果:" << result2.value_or(-1) << endl;

    return 0;
}

练习题

  1. 使用智能指针实现一个简单的资源管理类
  2. 使用lambda表达式实现自定义排序
  3. 实现一个支持移动语义的字符串类
  4. 使用constexpr实现编译期计算的数学函数
  5. 综合运用现代C++特性实现一个小项目