四、Lambda表达式深入
4.1 Lambda基础与捕获
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <memory>
void lambda_basics() {
// 基本lambda
auto add = [](int a, int b) { return a + b; };
std::cout << "add(3,5) = " << add(3, 5) << std::endl;
// ========== 捕获方式 ==========
int x = 10, y = 20;
// 值捕获
auto by_value = [x, y]() { return x + y; };
// 引用捕获
auto by_ref = [&x, &y]() { x++; y++; return x + y; };
// 隐式捕获
auto capture_all = [=]() { return x + y; }; // 值捕获所有
auto capture_all_ref = [&]() { return x + y; }; // 引用捕获所有
// 混合捕获
auto mixed = [=, &x]() { return x + y; }; // x引用,其他值
auto mixed2 = [&, x]() { return x + y; }; // x值,其他引用
// ========== 可变lambda ==========
int counter = 0;
auto mutable_lambda = [counter]() mutable {
return ++counter;
};
std::cout << "mutable: " << mutable_lambda() << std::endl;
std::cout << "mutable: " << mutable_lambda() << std::endl;
// ========== 泛型lambda(C++14) ==========
auto generic = [](auto a, auto b) { return a + b; };
std::cout << "generic int: " << generic(3, 5) << std::endl;
std::cout << "generic double: " << generic(3.14, 2.86) << std::endl;
// ========== 捕获初始化(C++14) ==========
auto init_capture = [ptr = std::make_unique<int>(42)]() {
return *ptr;
};
std::cout << "init capture: " << init_capture() << std::endl;
// ========== constexpr lambda(C++17) ==========
constexpr auto const_lambda = [](int n) { return n * n; };
constexpr int square = const_lambda(5);
std::cout << "constexpr square: " << square << std::endl;
}
// ========== Lambda在STL中的应用 ==========
void lambda_stl_demo() {
std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 排序(降序)
std::sort(vec.begin(), vec.end(), [](int a, int b) {
return a > b;
});
// 筛选偶数
std::vector<int> evens;
std::copy_if(vec.begin(), vec.end(), std::back_inserter(evens),
[](int x) { return x % 2 == 0; });
// 变换
std::transform(vec.begin(), vec.end(), vec.begin(),
[](int x) { return x * x; });
// 查找
auto it = std::find_if(vec.begin(), vec.end(),
[](int x) { return x > 50; });
// 累积
int sum = std::accumulate(vec.begin(), vec.end(), 0,
[](int acc, int x) { return acc + x; });
}
// ========== Lambda作为函数参数 ==========
template<typename Func>
void repeat(int n, Func func) {
for (int i = 0; i < n; i++) {
func(i);
}
}
void callback_demo() {
repeat(5, [](int i) {
std::cout << "回调: " << i << std::endl;
});
}
// ========== 递归Lambda ==========
void recursive_lambda() {
// 使用std::function实现递归
std::function<int(int)> factorial = [&](int n) -> int {
return (n <= 1) ? 1 : n * factorial(n - 1);
};
std::cout << "factorial(5) = " << factorial(5) << std::endl;
// C++14:使用auto实现递归(Y组合子)
auto fib = [](auto self, int n) -> int {
return (n <= 1) ? n : self(self, n - 1) + self(self, n - 2);
};
std::cout << "fib(10) = " << fib(fib, 10) << std::endl;
}
五、STL深入剖析
5.1 迭代器与适配器
#include <iostream>
#include <vector>
#include <list>
#include <iterator>
#include <algorithm>
#include <sstream>
// ========== 迭代器类别 ==========
void iterator_categories() {
// 输入迭代器:只读,单向
std::istream_iterator<int> in_it(std::cin);
// 输出迭代器:只写,单向
std::ostream_iterator<int> out_it(std::cout, " ");
// 前向迭代器:读写,单向(如forward_list)
// 双向迭代器:读写,双向(如list、set)
// 随机访问迭代器:读写,随机访问(如vector、array、deque)
std::vector<int> vec = {1, 2, 3, 4, 5};
// 反向迭代器
for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
}
// ========== 迭代器适配器 ==========
void iterator_adapters() {
std::vector<int> vec = {1, 2, 3, 4, 5};
std::list<int> lst;
// back_inserter
std::copy(vec.begin(), vec.end(), std::back_inserter(lst));
// front_inserter(需要容器支持push_front)
std::copy(vec.begin(), vec.end(), std::front_inserter(lst));
// inserter(在指定位置插入)
auto it = lst.begin();
std::advance(it, 2);
std::copy(vec.begin(), vec.end(), std::inserter(lst, it));
// istream_iterator
std::string data = "10 20 30 40 50";
std::istringstream iss(data);
std::istream_iterator<int> in_begin(iss), in_end;
std::vector<int> nums(in_begin, in_end);
// ostream_iterator
std::ostream_iterator<int> out_it(std::cout, ", ");
std::copy(nums.begin(), nums.end(), out_it);
}
// ========== 自定义迭代器 ==========
template<typename T>
class SimpleContainer {
private:
T* data;
size_t size;
public:
SimpleContainer(size_t n) : size(n), data(new T[n]) {}
~SimpleContainer() { delete[] data; }
// 迭代器类
class Iterator {
private:
T* ptr;
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = T;
using difference_type = ptrdiff_t;
using pointer = T*;
using reference = T&;
Iterator(T* p) : ptr(p) {}
reference operator*() const { return *ptr; }
pointer operator->() const { return ptr; }
Iterator& operator++() { ++ptr; return *this; }
Iterator operator++(int) { Iterator tmp = *this; ++ptr; return tmp; }
Iterator& operator--() { --ptr; return *this; }
Iterator operator--(int) { Iterator tmp = *this; --ptr; return tmp; }
Iterator& operator+=(difference_type n) { ptr += n; return *this; }
Iterator& operator-=(difference_type n) { ptr -= n; return *this; }
friend Iterator operator+(Iterator it, difference_type n) {
return Iterator(it.ptr + n);
}
friend difference_type operator-(const Iterator& a, const Iterator& b) {
return a.ptr - b.ptr;
}
bool operator==(const Iterator& other) const { return ptr == other.ptr; }
bool operator!=(const Iterator& other) const { return ptr != other.ptr; }
bool operator<(const Iterator& other) const { return ptr < other.ptr; }
};
Iterator begin() { return Iterator(data); }
Iterator end() { return Iterator(data + size); }
T& operator[](size_t i) { return data[i]; }
};
5.2 容器选择与性能
#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <chrono>
// ========== 容器性能对比 ==========
class Timer {
private:
std::chrono::high_resolution_clock::time_point start;
public:
Timer() : start(std::chrono::high_resolution_clock::now()) {}
~Timer() {
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
std::cout << "耗时: " << duration.count() << " μs" << std::endl;
}
};
void container_performance() {
const int N = 1000000;
// vector vs list 插入性能
{
Timer t;
std::vector<int> vec;
for (int i = 0; i < N; i++) {
vec.push_back(i);
}
std::cout << "vector push_back: ";
}
{
Timer t;
std::list<int> lst;
for (int i = 0; i < N; i++) {
lst.push_back(i);
}
std::cout << "list push_back: ";
}
// 随机访问性能
std::vector<int> vec(N);
std::list<int> lst(N);
for (int i = 0; i < N; i++) {
vec[i] = i;
lst.push_back(i);
}
{
Timer t;
int sum = 0;
for (int i = 0; i < N; i++) {
sum += vec[i];
}
std::cout << "vector随机访问: ";
}
{
Timer t;
int sum = 0;
auto it = lst.begin();
for (int i = 0; i < N; i++) {
sum += *it;
++it;
}
std::cout << "list顺序访问: ";
}
}
// ========== 容器选择指南 ==========
/*
* vector: 默认选择,连续内存,随机访问快,尾部插入删除快
* deque: 双端操作,随机访问,头部插入删除快
* list: 频繁中间插入删除,不需要随机访问
* forward_list: 单向链表,比list更节省内存
* set/map: 有序,需要快速查找、范围查询
* unordered_set/unordered_map: 哈希表,O(1)查找,无序
*/
// ========== 自定义分配器 ==========
template<typename T>
class PoolAllocator {
public:
using value_type = T;
PoolAllocator() = default;
template<typename U>
PoolAllocator(const PoolAllocator<U>&) {}
T* allocate(size_t n) {
std::cout << "分配 " << n << " 个对象" << std::endl;
return static_cast<T*>(::operator new(n * sizeof(T)));
}
void deallocate(T* p, size_t n) {
std::cout << "释放 " << n << " 个对象" << std::endl;
::operator delete(p);
}
};
void custom_allocator_demo() {
std::vector<int, PoolAllocator<int>> vec;
for (int i = 0; i < 10; i++) {
vec.push_back(i);
}
}
六、异常安全与错误处理
6.1 异常安全保证
#include <iostream>
#include <stdexcept>
#include <vector>
#include <memory>
// ========== 异常安全级别 ==========
/*
* 1. 基本保证:不泄漏资源,对象处于有效状态
* 2. 强保证:操作成功或回滚到之前状态
* 3. 不抛出保证:操作保证不会抛出异常
*/
// ========== 异常安全的类设计 ==========
class Account {
private:
std::string name;
double balance;
public:
Account(const std::string& n, double b) : name(n), balance(b) {}
// 强保证:使用copy-and-swap
void transfer(Account& other, double amount) {
if (amount < 0) throw std::invalid_argument("金额不能为负数");
if (balance < amount) throw std::runtime_error("余额不足");
// 创建临时副本
Account temp = *this;
Account temp_other = other;
// 修改副本
temp.balance -= amount;
temp_other.balance += amount;
// 交换(不抛出异常)
swap(temp);
other.swap(temp_other);
}
void swap(Account& other) noexcept {
using std::swap;
swap(name, other.name);
swap(balance, other.balance);
}
double getBalance() const { return balance; }
};
// ========== RAII与异常安全 ==========
class Transaction {
private:
std::vector<std::function<void()>> rollbacks;
bool committed = false;
public:
void addRollback(std::function<void()> rollback) {
rollbacks.push_back(rollback);
}
void commit() {
committed = true;
rollbacks.clear();
}
~Transaction() {
if (!committed) {
for (auto it = rollbacks.rbegin(); it != rollbacks.rend(); ++it) {
(*it)(); // 执行回滚
}
}
}
};
void transaction_demo() {
Transaction tx;
// 执行操作,注册回滚函数
tx.addRollback([]() {
std::cout << "回滚操作1" << std::endl;
});
tx.addRollback([]() {
std::cout << "回滚操作2" << std::endl;
});
// 如果所有操作成功
tx.commit();
}
// ========== noexcept说明符 ==========
void may_throw() {
throw std::runtime_error("可能会抛出异常");
}
void no_throw() noexcept {
// 保证不会抛出异常
}
void noexcept_demo() {
std::cout << "may_throw是否noexcept: " << noexcept(may_throw()) << std::endl;
std::cout << "no_throw是否noexcept: " << noexcept(no_throw()) << std::endl;
}
// ========== 异常与性能 ==========
/*
* 使用异常的好处:
* 1. 错误处理与正常逻辑分离
* 2. 构造函数失败的唯一方式
* 3. 跨函数传递错误信息
*
* 性能考虑:
* 1. 异常只在错误时发生,不应用于正常控制流
* 2. 现代编译器实现零成本异常(不抛出时无开销)
*/
七、并发编程
7.1 线程基础
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <future>
#include <atomic>
#include <chrono>
// ========== 基本线程管理 ==========
void thread_function(int id) {
std::cout << "线程 " << id << " 启动" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "线程 " << id << " 结束" << std::endl;
}
void thread_basics() {
std::thread t1(thread_function, 1);
std::thread t2(thread_function, 2);
// 等待线程完成
t1.join();
t2.join();
// 分离线程
std::thread t3(thread_function, 3);
t3.detach();
}
// ========== 线程安全与互斥锁 ==========
class ThreadSafeCounter {
private:
mutable std::mutex mtx;
int value;
public:
ThreadSafeCounter() : value(0) {}
void increment() {
std::lock_guard<std::mutex> lock(mtx);
++value;
}
int get() const {
std::lock_guard<std::mutex> lock(mtx);
return value;
}
// 使用scoped_lock同时锁定多个互斥量(C++17)
void exchange(ThreadSafeCounter& other) {
std::scoped_lock lock(mtx, other.mtx);
std::swap(value, other.value);
}
};
// ========== 死锁避免 ==========
class BankAccount {
private:
std::mutex mtx;
double balance;
public:
BankAccount(double b) : balance(b) {}
// 避免死锁:始终以相同顺序锁定
void transfer(BankAccount& other, double amount) {
std::lock(mtx, other.mtx);
std::lock_guard<std::mutex> lock1(mtx, std::adopt_lock);
std::lock_guard<std::mutex> lock2(other.mtx, std::adopt_lock);
if (balance >= amount) {
balance -= amount;
other.balance += amount;
}
}
};
// ========== 条件变量 ==========
class MessageQueue {
private:
std::queue<std::string> messages;
std::mutex mtx;
std::condition_variable cv;
public:
void send(const std::string& msg) {
{
std::lock_guard<std::mutex> lock(mtx);
messages.push(msg);
}
cv.notify_one();
}
std::string receive() {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [this] { return !messages.empty(); });
std::string msg = messages.front();
messages.pop();
return msg;
}
};
// ========== std::atomic与无锁编程 ==========
class LockFreeCounter {
private:
std::atomic<int> value;
public:
LockFreeCounter() : value(0) {}
void increment() {
value.fetch_add(1, std::memory_order_relaxed);
}
int get() const {
return value.load(std::memory_order_acquire);
}
// 比较并交换
bool compare_and_set(int expected, int desired) {
return value.compare_exchange_strong(expected, desired);
}
};
// ========== std::future与std::promise ==========
int long_computation(int n) {
std::this_thread::sleep_for(std::chrono::seconds(1));
return n * n;
}
void future_demo() {
// async异步执行
auto future1 = std::async(std::launch::async, long_computation, 10);
auto future2 = std::async(std::launch::async, long_computation, 20);
std::cout << "结果1: " << future1.get() << std::endl;
std::cout << "结果2: " << future2.get() << std::endl;
// packaged_task
std::packaged_task<int(int)> task(long_computation);
auto future = task.get_future();
std::thread t(std::move(task), 42);
std::cout << "结果: " << future.get() << std::endl;
t.join();
// promise
std::promise<int> promise;
auto future3 = promise.get_future();
std::thread t2([&promise] {
std::this_thread::sleep_for(std::chrono::seconds(1));
promise.set_value(100);
});
std::cout << "promise结果: " << future3.get() << std::endl;
t2.join();
}
// ========== 并行算法(C++17) ==========
#include <execution>
#include <vector>
#include <algorithm>
void parallel_algorithms() {
std::vector<int> vec(1000000);
std::iota(vec.begin(), vec.end(), 0);
// 并行排序
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 * x; });
}
八、性能优化
8.1 编译器优化
#include <iostream>
#include <chrono>
// ========== 内联函数 ==========
inline int inline_function(int x) {
return x * x;
}
// ========== 编译器优化提示 ==========
void optimization_hints() {
// 分支预测
int x = 10;
if (__builtin_expect(x > 0, 1)) { // 很可能为真
// 执行路径
}
// 预取
int arr[100];
__builtin_prefetch(&arr[50], 0, 3);
// 假设(优化提示)
__builtin_assume(x > 0);
}
// ========== 移动语义优化 ==========
std::vector<int> create_vector() {
std::vector<int> vec(1000000);
return vec; // RVO或移动语义
}
void move_optimization() {
auto vec = create_vector(); // 零拷贝
}
// ========== 小字符串优化 ==========
void small_string_optimization() {
std::string short_str = "short"; // 在栈上分配
std::string long_str = "this is a very long string that will be allocated on heap";
}
// ========== 性能测量 ==========
template<typename Func>
void measure_time(const std::string& name, Func func) {
auto start = std::chrono::high_resolution_clock::now();
func();
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
std::cout << name << "耗时: " << duration.count() << " μs" << std::endl;
}
// ========== 缓存友好访问 ==========
void cache_friendly() {
const int N = 10000;
std::vector<std::vector<int>> matrix(N, std::vector<int>(N));
// 缓存友好:按行访问
measure_time("按行访问", [&] {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
matrix[i][j] = i + j;
}
}
});
// 缓存不友好:按列访问
measure_time("按列访问", [&] {
for (int j = 0; j < N; j++) {
for (int i = 0; i < N; i++) {
matrix[i][j] = i + j;
}
}
});
}
知识体系图谱
C++进阶知识
├── RAII与资源管理
│ ├── 智能指针(unique_ptr/shared_ptr/weak_ptr)
│ ├── 移动语义与完美转发
│ └── 自定义资源管理类
├── 模板进阶
│ ├── 函数模板与类模板
│ ├── 模板特化与偏特化
│ ├── 可变参数模板
│ └── 模板元编程
├── 现代C++特性
│ ├── Lambda表达式
│ ├── 右值引用与移动语义
│ ├── auto/decltype
│ ├── constexpr
│ └── 结构化绑定
├── STL深入
│ ├── 迭代器与适配器
│ ├── 容器选择与性能
│ ├── 算法复杂度
│ └── 自定义分配器
├── 异常安全
│ ├── 异常安全级别
│ ├── RAII与异常安全
│ └── noexcept
├── 并发编程
│ ├── 线程与互斥锁
│ ├── 条件变量
│ ├── 原子操作
│ ├── future/promise
│ └── 并行算法
└── 性能优化
├── 编译器优化
├── 移动语义
├── 缓存友好
└── 性能测量
进阶开发者的标志是能够理解语言特性背后的设计哲学,能够编写异常安全、高性能的代码,能够在多线程环境中正确同步,能够运用模板元编程在编译期解决问题。愿你在C++的世界里,不仅掌握语言的特性,更理解编程的智慧。
来源:
https://app-aes4wxahovsx.appmiaoda.com/