C11基础语法1. auto 自动类型推导不用写复杂类型编译器自动推。auto a 10; // int auto b 3.14; // double auto vec vectorint{1,2,3};2. 范围 for 循环遍历容器超简单。vectorint v {1,2,3}; for (auto x : v) { cout x;3. nullptr 空指针比NULL安全不会和整数混淆。int* p nullptr;4. 列表初始化统一初始化风格更安全。vectorint v{1,2,3}; int a{10};5. override / final防止写错虚函数强制约束void func() override; // 必须重写 void func() final; // 不能再重写智能指针不用手动 delete自动释放内存。1. std::unique_ptr独占指针同一时间只有一个指针拥有对象最常用、最高效。#include memory unique_ptrint p1(new int(10)); auto p2 make_uniqueint(20); // C14 // 离开作用域自动释放无需 delete2. std::shared_ptr共享指针多个指针共享对象引用计数为 0 时释放。shared_ptrint p1 make_sharedint(10); shared_ptrint p2 p1; // 计数1 // 最后一个指针销毁时内存释放3. std::weak_ptr解决循环引用配合 shared_ptr 使用不增加引用计数。weak_ptrint wp sp;右值引用与移动语义1.什么是右值临时对象即将销毁、没人用的值。int a 10; // a 是左值 int b a 1; // a1 是右值2. 右值引用 专门绑定临时对象int rr 10; // 绑定右值3. 移动语义把临时对象的资源 “偷” 过来不拷贝速度极快。string a hello; string b move(a); // 移动不是拷贝 // a 变成空b 直接接管资源4. 移动构造 / 移动赋值C11 自动生成大幅优化容器性能。MyClass(MyClass other) { // 偷资源 }一句话总结拷贝 复制数据移动 转让所有权Lambda 表达式像变量一样写函数非常方便。可以随时定义、就地使用的匿名函数不用单独写函数名[捕获列表] (参数) - 返回值 { 函数体 }; 捕获列表 []值捕获外部变量只读 []引用捕获外部变量可修改 [x, y]x 值捕获y 引用捕获 [this]在类里捕获当前对象 auto add [](int a, int b) { return a b; }; cout add(1,2); // 输出3lambda表达式的本质是仿函数 类里面重写了运算符重载 因此可以向函数指针一样使用。并发编程多线程标准库最核心 4 大件std::thread 创建线程std::mutex 互斥锁std::condition_variable:条件变量线程等待与唤醒std::atomic原子变量1.std::thread创建线程1基础用法#include iostream #include thread using namespace std; void func() { cout 子线程运行\n; } int main() { thread t(func); // 启动线程 t.join(); // 等待线程结束必须写 return 0; }2带参数void print(int a, string s) { cout a s endl; } int main() { thread t(print, 10, hello); t.join(); }3Lambda 线程最常用int main() { thread t([]() { cout Lambda 线程\n; }); t.join(); }4两个关键函数t.join()等待线程结束主线程阻塞t.detach()分离线程后台运行主线程不管它2.std::mutex互斥锁解决线程安全1基础锁int num 0; std::mutex mtx; void add() { for (int i 0;num 10000000; i) { mtx.lock(); // 加锁 num; // 同一时间只有一个线程能执行 mtx.unlock(); // 解锁 } } int main() { std::thread t(add); std::thread t1(add); t.join(); t1.join(); std::cout num num; }2推荐std::lock_guard自动锁离开作用域自动解锁不会忘 unlockint num 0; std::mutex mtx; void add() { for (int i 0;num 10000000; i) { std::lock_guardstd::mutexlock(mtx); num; // 同一时间只有一个线程能执行 } } int main() { std::thread t(add); std::thread t1(add); t.join(); t1.join(); std::cout num num; }3更灵活std::unique_lock支持手动锁 / 解锁、配合条件变量int num 0; std::mutex mtx; std::unique_lockstd::mutex lock(mtx); void add() { for (int i 0;num 10000000; i) { lock.lock(); num; // 同一时间只有一个线程能执行 lock.unlock(); } } int main() { std::thread t(add); std::thread t1(add); t.join(); t1.join(); std::cout num num; }3.std::condition_variable条件变量等待 / 唤醒必须配合互斥锁使用用于生产者 - 消费者模型线程 A没数据 →wait()线程 B生产数据 →notify_one()唤醒 Astd::mutex mtx; std::condition_variable cv; std::queueint q; void producer() { for (int i 0;i 5;i) { std::unique_lockstd::mutexlock(mtx); q.push(i); std::cout 生产 i std::endl; cv.notify_one(); // 唤醒消费者 } } void consumer() { while (true) { std::unique_lockstd::mutexlock(mtx); cv.wait(lock, [] {return !q.empty();}); int val q.front(); q.pop(); std::cout 消费 val std:: endl; if (val 4) break; } } int main() { std::thread t1(consumer); std::thread t(producer); t1.join();t.join(); std::cout q.size(); }4.std::atomic原子变量无锁安全简单类型int/bool不用加锁原子操作 线程安全std::atomicintnum 0;//线程安全 void add() { for (int i 0;num 10000000; i) { num; // 同一时间只有一个线程能执行 } } int main() { std::thread t(add); std::thread t1(add); t.join(); t1.join(); std::cout num num; }异步编程核心三剑客std::async启动异步任务最简单直接用std::future获取异步结果像 “提货单”std::promise手动设置异步结果底层std::packaged_task包装任务绑定 future中间层1.std::async std::future作用后台开线程跑函数用future拿返回值不用自己创建 thread超级安全关键点async(任务, 参数...)自动创建线程futureT用来接收结果fut.get()只能调用一次调用时会阻塞等待任务完成#include iostream #include future // 异步头文件 #include thread #include chrono using namespace std; // 耗时任务 int long_task(int a, int b) { this_thread::sleep_for(chrono::seconds(2)); // 模拟耗时 return a b; } int main() { // 1. 启动异步任务 futureint fut async(long_task, 10, 20); cout 异步任务已启动主线程继续做别的事... endl; // 2. 阻塞等待结果并获取返回值 int res fut.get(); cout 结果 res endl; return 0; }2.std::async 两种启动策略立即启动策略async(launch::async, 任务);延迟启动策略async(launch:deferred, 任务);3.future 常用方法fut.get(); // 获取结果阻塞等待 fut.wait(); // 只等待不拿结果 fut.valid(); // 判断 future 是否有效 fut.wait_for(1s); // 等待最多1秒超时返回4.std::promise手动传值作用手动设置一个值 / 异常让另一个线程通过 future 获取。#include iostream #include thread #include future using namespace std; // 子线程函数接收 promise手动设置结果 void my_thread(promiseint prom) { // 计算... prom.set_value(2025); // 手动把结果塞进去 } int main() { // 1. 创建 promise promiseint prom; // 2. 获取关联的 future取货单 futureint fut prom.get_future(); // 3. 把 promise 交给子线程必须 move thread t(my_thread, move(prom)); // 4. 主线程等待结果 cout 结果 fut.get() endl; t.join(); return 0; }5.std::packaged_task包装任务作用把一个函数包装起来自动把返回值绑定到 future。#include iostream #include future #include thread using namespace std; // 普通函数 int add(int a, int b) { return a b; } int main() { // 1. 包装函数返回值 int参数 int int packaged_taskint(int, int) task(add); // 2. 获取 future futureint fut task.get_future(); // 3. 交给线程执行 thread t(move(task), 10, 20); // 4. 拿结果 cout fut.get() endl; // 30 t.join(); return 0; }
C++高级进阶--夯实进阶基础--c11(2)
C11基础语法1. auto 自动类型推导不用写复杂类型编译器自动推。auto a 10; // int auto b 3.14; // double auto vec vectorint{1,2,3};2. 范围 for 循环遍历容器超简单。vectorint v {1,2,3}; for (auto x : v) { cout x;3. nullptr 空指针比NULL安全不会和整数混淆。int* p nullptr;4. 列表初始化统一初始化风格更安全。vectorint v{1,2,3}; int a{10};5. override / final防止写错虚函数强制约束void func() override; // 必须重写 void func() final; // 不能再重写智能指针不用手动 delete自动释放内存。1. std::unique_ptr独占指针同一时间只有一个指针拥有对象最常用、最高效。#include memory unique_ptrint p1(new int(10)); auto p2 make_uniqueint(20); // C14 // 离开作用域自动释放无需 delete2. std::shared_ptr共享指针多个指针共享对象引用计数为 0 时释放。shared_ptrint p1 make_sharedint(10); shared_ptrint p2 p1; // 计数1 // 最后一个指针销毁时内存释放3. std::weak_ptr解决循环引用配合 shared_ptr 使用不增加引用计数。weak_ptrint wp sp;右值引用与移动语义1.什么是右值临时对象即将销毁、没人用的值。int a 10; // a 是左值 int b a 1; // a1 是右值2. 右值引用 专门绑定临时对象int rr 10; // 绑定右值3. 移动语义把临时对象的资源 “偷” 过来不拷贝速度极快。string a hello; string b move(a); // 移动不是拷贝 // a 变成空b 直接接管资源4. 移动构造 / 移动赋值C11 自动生成大幅优化容器性能。MyClass(MyClass other) { // 偷资源 }一句话总结拷贝 复制数据移动 转让所有权Lambda 表达式像变量一样写函数非常方便。可以随时定义、就地使用的匿名函数不用单独写函数名[捕获列表] (参数) - 返回值 { 函数体 }; 捕获列表 []值捕获外部变量只读 []引用捕获外部变量可修改 [x, y]x 值捕获y 引用捕获 [this]在类里捕获当前对象 auto add [](int a, int b) { return a b; }; cout add(1,2); // 输出3lambda表达式的本质是仿函数 类里面重写了运算符重载 因此可以向函数指针一样使用。并发编程多线程标准库最核心 4 大件std::thread 创建线程std::mutex 互斥锁std::condition_variable:条件变量线程等待与唤醒std::atomic原子变量1.std::thread创建线程1基础用法#include iostream #include thread using namespace std; void func() { cout 子线程运行\n; } int main() { thread t(func); // 启动线程 t.join(); // 等待线程结束必须写 return 0; }2带参数void print(int a, string s) { cout a s endl; } int main() { thread t(print, 10, hello); t.join(); }3Lambda 线程最常用int main() { thread t([]() { cout Lambda 线程\n; }); t.join(); }4两个关键函数t.join()等待线程结束主线程阻塞t.detach()分离线程后台运行主线程不管它2.std::mutex互斥锁解决线程安全1基础锁int num 0; std::mutex mtx; void add() { for (int i 0;num 10000000; i) { mtx.lock(); // 加锁 num; // 同一时间只有一个线程能执行 mtx.unlock(); // 解锁 } } int main() { std::thread t(add); std::thread t1(add); t.join(); t1.join(); std::cout num num; }2推荐std::lock_guard自动锁离开作用域自动解锁不会忘 unlockint num 0; std::mutex mtx; void add() { for (int i 0;num 10000000; i) { std::lock_guardstd::mutexlock(mtx); num; // 同一时间只有一个线程能执行 } } int main() { std::thread t(add); std::thread t1(add); t.join(); t1.join(); std::cout num num; }3更灵活std::unique_lock支持手动锁 / 解锁、配合条件变量int num 0; std::mutex mtx; std::unique_lockstd::mutex lock(mtx); void add() { for (int i 0;num 10000000; i) { lock.lock(); num; // 同一时间只有一个线程能执行 lock.unlock(); } } int main() { std::thread t(add); std::thread t1(add); t.join(); t1.join(); std::cout num num; }3.std::condition_variable条件变量等待 / 唤醒必须配合互斥锁使用用于生产者 - 消费者模型线程 A没数据 →wait()线程 B生产数据 →notify_one()唤醒 Astd::mutex mtx; std::condition_variable cv; std::queueint q; void producer() { for (int i 0;i 5;i) { std::unique_lockstd::mutexlock(mtx); q.push(i); std::cout 生产 i std::endl; cv.notify_one(); // 唤醒消费者 } } void consumer() { while (true) { std::unique_lockstd::mutexlock(mtx); cv.wait(lock, [] {return !q.empty();}); int val q.front(); q.pop(); std::cout 消费 val std:: endl; if (val 4) break; } } int main() { std::thread t1(consumer); std::thread t(producer); t1.join();t.join(); std::cout q.size(); }4.std::atomic原子变量无锁安全简单类型int/bool不用加锁原子操作 线程安全std::atomicintnum 0;//线程安全 void add() { for (int i 0;num 10000000; i) { num; // 同一时间只有一个线程能执行 } } int main() { std::thread t(add); std::thread t1(add); t.join(); t1.join(); std::cout num num; }异步编程核心三剑客std::async启动异步任务最简单直接用std::future获取异步结果像 “提货单”std::promise手动设置异步结果底层std::packaged_task包装任务绑定 future中间层1.std::async std::future作用后台开线程跑函数用future拿返回值不用自己创建 thread超级安全关键点async(任务, 参数...)自动创建线程futureT用来接收结果fut.get()只能调用一次调用时会阻塞等待任务完成#include iostream #include future // 异步头文件 #include thread #include chrono using namespace std; // 耗时任务 int long_task(int a, int b) { this_thread::sleep_for(chrono::seconds(2)); // 模拟耗时 return a b; } int main() { // 1. 启动异步任务 futureint fut async(long_task, 10, 20); cout 异步任务已启动主线程继续做别的事... endl; // 2. 阻塞等待结果并获取返回值 int res fut.get(); cout 结果 res endl; return 0; }2.std::async 两种启动策略立即启动策略async(launch::async, 任务);延迟启动策略async(launch:deferred, 任务);3.future 常用方法fut.get(); // 获取结果阻塞等待 fut.wait(); // 只等待不拿结果 fut.valid(); // 判断 future 是否有效 fut.wait_for(1s); // 等待最多1秒超时返回4.std::promise手动传值作用手动设置一个值 / 异常让另一个线程通过 future 获取。#include iostream #include thread #include future using namespace std; // 子线程函数接收 promise手动设置结果 void my_thread(promiseint prom) { // 计算... prom.set_value(2025); // 手动把结果塞进去 } int main() { // 1. 创建 promise promiseint prom; // 2. 获取关联的 future取货单 futureint fut prom.get_future(); // 3. 把 promise 交给子线程必须 move thread t(my_thread, move(prom)); // 4. 主线程等待结果 cout 结果 fut.get() endl; t.join(); return 0; }5.std::packaged_task包装任务作用把一个函数包装起来自动把返回值绑定到 future。#include iostream #include future #include thread using namespace std; // 普通函数 int add(int a, int b) { return a b; } int main() { // 1. 包装函数返回值 int参数 int int packaged_taskint(int, int) task(add); // 2. 获取 future futureint fut task.get_future(); // 3. 交给线程执行 thread t(move(task), 10, 20); // 4. 拿结果 cout fut.get() endl; // 30 t.join(); return 0; }