C++ 面试总结
目录
1. C++ 基础知识
1.1 数据类型与类型转换
基本数据类型
类型转换
1.2 const 关键字
1.3 引用
1.4 指针
1.5 函数
2. 内存管理
2.1 内存布局
2.2 动态内存管理
2.3 智能指针
2.4 内存泄漏检测
3. 面向对象编程
3.1 类的基本概念
3.2 继承
3.3 多态
3.4 RAII (Resource Acquisition Is Initialization)
4. 模板与泛型编程
4.1 函数模板
4.2 类模板
4.3 模板元编程
4.4 概念与约束 (C++20)
5. STL 标准模板库
5.1 容器
序列容器
关联容器
无序容器 (C++11)
容器适配器
5.2 迭代器
5.3 算法
5.4 函数对象与Lambda
6. 现代 C++ 特性
6.1 C++11 特性
6.2 C++14 特性
6.3 C++17 特性
6.4 C++20 特性
7. 设计模式
7.1 创建型模式
单例模式
工厂模式
建造者模式
7.2 结构型模式
适配器模式
装饰器模式
代理模式
7.3 行为型模式
观察者模式
策略模式
命令模式
8. 性能优化
8.1 编译器优化
8.2 内存优化
8.3 算法优化
8.4 并行优化
8.5 性能分析工具
9. 多线程与并发
9.1 线程基础
9.2 互斥量与锁
9.3 条件变量
9.4 原子操作
9.5 并发工具
10. 编译与链接
10.1 编译过程
10.2 链接类型
10.3 符号可见性
10.4 模板实例化
11. 常见面试题
11.1 语言特性相关
1. 指针和引用的区别?
2. const的用法?
3. static的用法?
4. 虚函数的实现原理?
5. 什么是RAII?
11.2 内存相关
1. 内存泄漏如何检测和避免?
2. new/malloc的区别?
3. 智能指针的实现原理?
11.3 多态和继承
1. 如何实现多态?
2. 虚函数和纯虚函数的区别?
3. 多重继承的问题和解决方案?
4. override和final的作用?
11.4 STL相关
1. vector的扩容机制?
2. map和unordered_map的区别?
3. 迭代器失效问题?
11.5 现代C++特性
1. 移动语义的优势?
2. lambda表达式的实现原理?
3. constexpr和const的区别?
12. 最佳实践
12.1 代码设计原则
SOLID原则
12.2 资源管理
12.3 错误处理
12.4 性能优化建议
12.5 代码风格和规范
12.6 测试和调试
1. C++ 基础知识
1.1 数据类型与类型转换
基本数据类型
// 整型
short, int, long, long long
unsigned short, unsigned int, unsigned long, unsigned long long// 浮点型
float, double, long double// 字符型
char, wchar_t, char16_t, char32_t// 布尔型
bool// 空类型
void// 空指针
nullptr (C++11)
类型转换
// C风格转换(不推荐)
int a = (int)3.14;// C++风格转换(推荐)
// 1. static_cast - 用于基本类型转换
double d = 3.14;
int i = static_cast<int>(d);// 2. const_cast - 移除const属性
const int* cp = &i;
int* p = const_cast<int*>(cp);// 3. dynamic_cast - 用于多态类型的安全向下转换
class Base { virtual void func() {} };
class Derived : public Base {};
Base* base = new Derived;
Derived* derived = dynamic_cast<Derived*>(base);// 4. reinterpret_cast - 用于指针类型之间的转换
int* ip = &i;
char* cp = reinterpret_cast<char*>(ip);
1.2 const 关键字
// 常量变量
const int a = 10;// 常量指针 - 指针指向的内容不可修改
const int* p1 = &a;// 指针常量 - 指针本身不可修改
int* const p2 = &a;// 常量指针常量 - 指针和指向的内容都不可修改
const int* const p3 = &a;// 常量成员函数 - 不修改成员变量
class MyClass {
public:int getValue() const { return value; }
private:int value;
};// mutable - 允许在const成员函数中修改
class Counter {mutable int count = 0;
public:void increment() const { count++; }
};
1.3 引用
// 左值引用
int a = 10;
int& ref = a;// const引用可以绑定到右值
const int& cref = 10;// 右值引用 (C++11)
int&& rref = 10;
int&& rref2 = std::move(a);// 完美转发 (C++11)
template<typename T>
void forward_func(T&& t) {other_func(std::forward<T>(t));
}// 引用折叠规则
// T& & -> T&
// T& && -> T&
// T&& & -> T&
// T&& && -> T&&
1.4 指针
// 普通指针
int* p = new int(10);
delete p;// 数组指针
int arr[5] = {1, 2, 3, 4, 5};
int* arrPtr = arr;// 指针数组
int* ptrArr[5];// 函数指针
int add(int a, int b) { return a + b; }
int (*funcPtr)(int, int) = add;
int result = funcPtr(1, 2);// 成员函数指针
class MyClass {
public:void func() {}
};
void (MyClass::*memFuncPtr)() = &MyClass::func;
MyClass obj;
(obj.*memFuncPtr)();
1.5 函数
// 函数重载
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }// 默认参数
void func(int a, int b = 10) {}// 内联函数
inline int max(int a, int b) { return a > b ? a : b; }// 函数模板
template<typename T>
T max(T a, T b) { return a > b ? a : b; }// 可变参数模板 (C++11)
template<typename... Args>
void print(Args... args) {((std::cout << args << " "), ...);
}// lambda表达式 (C++11)
auto lambda = [](int a, int b) -> int { return a + b; };
2. 内存管理
2.1 内存布局
// 程序内存布局(从低地址到高地址)
// 1. 代码段(Text Segment)- 存放程序代码
// 2. 数据段(Data Segment)- 存放已初始化的全局变量和静态变量
// 3. BSS段 - 存放未初始化的全局变量和静态变量
// 4. 堆(Heap)- 动态内存分配,向上增长
// 5. 栈(Stack)- 存放局部变量、函数参数等,向下增长
2.2 动态内存管理
// new/delete
int* p1 = new int(10);
delete p1;int* arr = new int[10];
delete[] arr;// placement new
char buffer[sizeof(MyClass)];
MyClass* obj = new (buffer) MyClass();
obj->~MyClass(); // 需要手动调用析构函数// operator new/delete重载
class MyClass {
public:void* operator new(size_t size) {std::cout << "Custom new\n";return ::operator new(size);}void operator delete(void* p) {std::cout << "Custom delete\n";::operator delete(p);}
};// 内存池实现示例
template<typename T, size_t BlockSize = 4096>
class MemoryPool {
private:union Slot {T element;Slot* next;};typedef char* data_pointer;typedef Slot slot_type;typedef Slot* slot_pointer;slot_pointer currentBlock;slot_pointer currentSlot;slot_pointer lastSlot;slot_pointer freeSlots;public:MemoryPool() : currentBlock(nullptr), currentSlot(nullptr),lastSlot(nullptr), freeSlots(nullptr) {}~MemoryPool() {slot_pointer curr = currentBlock;while (curr != nullptr) {slot_pointer prev = curr->next;operator delete(reinterpret_cast<void*>(curr));curr = prev;}}T* allocate() {if (freeSlots != nullptr) {slot_pointer result = freeSlots;freeSlots = freeSlots->next;return reinterpret_cast<T*>(result);} else {if (currentSlot >= lastSlot) {allocateBlock();}return reinterpret_cast<T*>(currentSlot++);}}void deallocate(T* p) {if (p != nullptr) {reinterpret_cast<slot_pointer>(p)->next = freeSlots;freeSlots = reinterpret_cast<slot_pointer>(p);}}private:void allocateBlock() {data_pointer newBlock = reinterpret_cast<data_pointer>(operator new(BlockSize));reinterpret_cast<slot_pointer>(newBlock)->next = currentBlock;currentBlock = reinterpret_cast<slot_pointer>(newBlock);data_pointer body = newBlock + sizeof(slot_pointer);size_t bodyPadding = (alignof(slot_type) - body) % alignof(slot_type);currentSlot = reinterpret_cast<slot_pointer>(body + bodyPadding);lastSlot = reinterpret_cast<slot_pointer>(newBlock + BlockSize - sizeof(slot_type) + 1);}
};
2.3 智能指针
// unique_ptr - 独占所有权
std::unique_ptr<int> up1(new int(10));
std::unique_ptr<int> up2 = std::make_unique<int>(20); // C++14// 转移所有权
std::unique_ptr<int> up3 = std::move(up1);// shared_ptr - 共享所有权
std::shared_ptr<int> sp1(new int(10));
std::shared_ptr<int> sp2 = std::make_shared<int>(20); // 推荐
std::shared_ptr<int> sp3 = sp1; // 引用计数+1// weak_ptr - 弱引用,解决循环引用
std::shared_ptr<Node> node1 = std::make_shared<Node>();
std::shared_ptr<Node> node2 = std::make_shared<Node>();
node1->next = node2;
node2->prev = std::weak_ptr<Node>(node1); // 使用weak_ptr避免循环引用// 自定义删除器
auto deleter = [](int* p) {std::cout << "Custom deleter\n";delete p;
};
std::unique_ptr<int, decltype(deleter)> up(new int(10), deleter);
std::shared_ptr<int> sp(new int(10), deleter);
2.4 内存泄漏检测
// 简单的内存泄漏检测
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif// 使用工具
// 1. Valgrind (Linux)
// 2. AddressSanitizer
// 3. Visual Studio Diagnostic Tools
// 4. CRT Debug Heap (Windows)
3. 面向对象编程
3.1 类的基本概念
class MyClass {
private:int privateData;protected:int protectedData;public:int publicData;// 构造函数MyClass() : privateData(0), protectedData(0), publicData(0) {}// 带参数的构造函数MyClass(int a, int b, int c) : privateData(a), protectedData(b), publicData(c) {}// 拷贝构造函数MyClass(const MyClass& other) : privateData(other.privateData),protectedData(other.protectedData),publicData(other.publicData) {}// 移动构造函数 (C++11)MyClass(MyClass&& other) noexcept: privateData(std::move(other.privateData)),protectedData(std::move(other.protectedData)),publicData(std::move(other.publicData)) {}// 拷贝赋值运算符MyClass& operator=(const MyClass& other) {if (this != &other) {privateData = other.privateData;protectedData = other.protectedData;publicData = other.publicData;}return *this;}// 移动赋值运算符 (C++11)MyClass& operator=(MyClass&& other) noexcept {if (this != &other) {privateData = std::move(other.privateData);protectedData = std::move(other.protectedData);publicData = std::move(other.publicData);}return *this;}// 析构函数~MyClass() {}// 成员函数void memberFunction() {}// 常量成员函数int getData() const { return privateData; }// 静态成员函数static void staticFunction() {}// 友元函数friend void friendFunction(MyClass& obj);// 友元类friend class FriendClass;
};// 静态成员变量初始化
int MyClass::staticData = 0;
3.2 继承
// 单继承
class Base {
public:virtual void func() { std::cout << "Base::func()\n"; }virtual ~Base() {}
};class Derived : public Base {
public:void func() override { std::cout << "Derived::func()\n"; }
};// 多继承
class A {
public:virtual void funcA() {}
};class B {
public:virtual void funcB() {}
};class C : public A, public B {
public:void funcA() override {}void funcB() override {}
};// 虚继承 - 解决菱形继承问题
class Animal {
public:int age;
};class Mammal : virtual public Animal {};
class Bird : virtual public Animal {};
class Bat : public Mammal, public Bird {}; // Bat只有一份Animal的实例// 继承中的构造和析构顺序
// 构造:基类 -> 成员 -> 派生类
// 析构:派生类 -> 成员 -> 基类
3.3 多态
// 编译时多态 - 函数重载、模板
template<typename T>
T max(T a, T b) { return a > b ? a : b; }// 运行时多态 - 虚函数
class Shape {
public:virtual double area() const = 0; // 纯虚函数virtual ~Shape() {}
};class Circle : public Shape {
private:double radius;
public:Circle(double r) : radius(r) {}double area() const override {return 3.14159 * radius * 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;}
};// 虚函数表(vtable)原理
// 每个包含虚函数的类都有一个虚函数表
// 对象的内存布局中包含一个指向虚函数表的指针(vptr)
3.4 RAII (Resource Acquisition Is Initialization)
// RAII 示例 - 文件句柄管理
class FileHandler {
private:FILE* file;
public:explicit FileHandler(const char* filename, const char* mode) {file = fopen(filename, mode);if (!file) {throw std::runtime_error("Failed to open file");}}~FileHandler() {if (file) {fclose(file);}}// 禁用拷贝FileHandler(const FileHandler&) = delete;FileHandler& operator=(const FileHandler&) = delete;// 允许移动FileHandler(FileHandler&& other) noexcept : file(other.file) {other.file = nullptr;}FileHandler& operator=(FileHandler&& other) noexcept {if (this != &other) {if (file) fclose(file);file = other.file;other.file = nullptr;}return *this;}void write(const char* data) {if (file) {fputs(data, file);}}
};// 使用RAII管理互斥锁
void threadSafeFunction() {static std::mutex mtx;std::lock_guard<std::mutex> lock(mtx); // RAII// 临界区代码
} // lock自动释放
4. 模板与泛型编程
4.1 函数模板
// 基本函数模板
template<typename T>
T max(T a, T b) {return a > b ? a : b;
}// 模板特化
template<>
const char* max<const char*>(const char* a, const char* b) {return strcmp(a, b) > 0 ? a : b;
}// 可变参数模板 (C++11)
template<typename... Args>
void print(Args... args) {((std::cout << args << " "), ...); // C++17 折叠表达式
}// C++11/14的递归实现
template<typename T>
void print(T&& t) {std::cout << t << std::endl;
}template<typename T, typename... Args>
void print(T&& t, Args&&... args) {std::cout << t << " ";print(std::forward<Args>(args)...);
}
4.2 类模板
// 基本类模板
template<typename T>
class Stack {
private:std::vector<T> elements;
public:void push(const T& elem) {elements.push_back(elem);}void pop() {if (!elements.empty()) {elements.pop_back();}}T& top() {return elements.back();}bool empty() const {return elements.empty();}
};// 模板类的特化
template<>
class Stack<bool> {
private:std::vector<bool> elements; // 使用位存储优化
public:// 特殊实现...
};// 部分特化
template<typename T>
class Stack<T*> {
private:std::vector<T*> elements;
public:// 针对指针类型的特殊实现
};
4.3 模板元编程
// 编译时计算阶乘
template<int N>
struct Factorial {static constexpr int value = N * Factorial<N-1>::value;
};template<>
struct Factorial<0> {static constexpr int value = 1;
};// C++14 constexpr函数
constexpr int factorial(int n) {return n <= 1 ? 1 : n * factorial(n - 1);
}// SFINAE (Substitution Failure Is Not An Error)
template<typename T>
typename std::enable_if<std::is_integral<T>::value, bool>::type
is_odd(T i) {return i % 2;
}// C++17 if constexpr
template<typename T>
auto process(T t) {if constexpr (std::is_integral_v<T>) {return t + 1;} else {return t;}
}// 类型萃取
template<typename T>
struct remove_reference {typedef T type;
};template<typename T>
struct remove_reference<T&> {typedef T type;
};template<typename T>
struct remove_reference<T&&> {typedef T type;
};template<typename T>
using remove_reference_t = typename remove_reference<T>::type;
4.4 概念与约束 (C++20)
// 概念定义
template<typename T>
concept Addable = requires(T a, T b) {{ a + b } -> std::same_as<T>;
};// 使用概念约束模板
template<Addable T>
T add(T a, T b) {return a + b;
}// requires子句
template<typename T>requires std::is_integral_v<T> || std::is_floating_point_v<T>
T multiply(T a, T b) {return a * b;
}// 约束auto
Addable auto sum = add(1, 2);
5. STL 标准模板库
5.1 容器
序列容器
// vector - 动态数组
std::vector<int> vec = {1, 2, 3, 4, 5};
vec.push_back(6);
vec.pop_back();
vec.reserve(100); // 预分配容量
vec.resize(10); // 改变大小// deque - 双端队列
std::deque<int> deq;
deq.push_front(1);
deq.push_back(2);
deq.pop_front();
deq.pop_back();// list - 双向链表
std::list<int> lst;
lst.push_back(1);
lst.push_front(0);
lst.insert(lst.begin(), -1);
lst.remove(0); // 删除所有值为0的元素// forward_list - 单向链表 (C++11)
std::forward_list<int> flst;
flst.push_front(1);
flst.insert_after(flst.begin(), 2);// array - 固定大小数组 (C++11)
std::array<int, 5> arr = {1, 2, 3, 4, 5};
关联容器
// set/multiset - 有序集合
std::set<int> s;
s.insert(3);
s.insert(1);
s.insert(2);
// 元素自动排序:1, 2, 3std::multiset<int> ms;
ms.insert(1);
ms.insert(1); // 允许重复// map/multimap - 有序映射
std::map<std::string, int> m;
m["apple"] = 1;
m["banana"] = 2;
m.insert({"orange", 3});// 自定义比较器
struct CompareLength {bool operator()(const std::string& a, const std::string& b) const {return a.length() < b.length();}
};
std::map<std::string, int, CompareLength> customMap;
无序容器 (C++11)
// unordered_set/unordered_multiset
std::unordered_set<int> us;
us.insert(1);
us.insert(2);
us.insert(3);// unordered_map/unordered_multimap
std::unordered_map<std::string, int> um;
um["apple"] = 1;
um["banana"] = 2;// 自定义哈希函数
struct Person {std::string name;int age;
};struct PersonHash {std::size_t operator()(const Person& p) const {return std::hash<std::string>()(p.name) ^ (std::hash<int>()(p.age) << 1);}
};struct PersonEqual {bool operator()(const Person& a, const Person& b) const {return a.name == b.name && a.age == b.age;}
};std::unordered_map<Person, int, PersonHash, PersonEqual> personMap;
容器适配器
// stack - 栈
std::stack<int> stk;
stk.push(1);
stk.push(2);
int top = stk.top();
stk.pop();// queue - 队列
std::queue<int> q;
q.push(1);
q.push(2);
int front = q.front();
q.pop();// priority_queue - 优先队列
std::priority_queue<int> pq; // 默认大顶堆
pq.push(3);
pq.push(1);
pq.push(4);
int max = pq.top(); // 4// 小顶堆
std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap;
5.2 迭代器
// 迭代器类型
// 1. 输入迭代器 (Input Iterator)
// 2. 输出迭代器 (Output Iterator)
// 3. 前向迭代器 (Forward Iterator)
// 4. 双向迭代器 (Bidirectional Iterator)
// 5. 随机访问迭代器 (Random Access Iterator)// 迭代器使用
std::vector<int> vec = {1, 2, 3, 4, 5};// 正向迭代
for (auto it = vec.begin(); it != vec.end(); ++it) {std::cout << *it << " ";
}// 反向迭代
for (auto rit = vec.rbegin(); rit != vec.rend(); ++rit) {std::cout << *rit << " ";
}// const迭代器
for (auto cit = vec.cbegin(); cit != vec.cend(); ++cit) {// *cit = 10; // 错误,不能修改
}// 迭代器失效问题
std::vector<int> v = {1, 2, 3, 4, 5};
for (auto it = v.begin(); it != v.end(); ) {if (*it == 3) {it = v.erase(it); // erase返回下一个有效迭代器} else {++it;}
}
5.3 算法
// 非修改序列操作
std::vector<int> vec = {1, 2, 3, 4, 5};// find
auto it = std::find(vec.begin(), vec.end(), 3);// find_if
auto it2 = std::find_if(vec.begin(), vec.end(), [](int x) { return x > 3; });// count
int cnt = std::count(vec.begin(), vec.end(), 3);// all_of, any_of, none_of (C++11)
bool allPositive = std::all_of(vec.begin(), vec.end(), [](int x) { return x > 0; });// 修改序列操作
// copy
std::vector<int> vec2(5);
std::copy(vec.begin(), vec.end(), vec2.begin());// transform
std::transform(vec.begin(), vec.end(), vec.begin(), [](int x) { return x * 2; });// replace
std::replace(vec.begin(), vec.end(), 3, 30);// 排序和相关操作
// sort
std::sort(vec.begin(), vec.end());
std::sort(vec.begin(), vec.end(), std::greater<int>());// partial_sort
std::partial_sort(vec.begin(), vec.begin() + 3, vec.end());// nth_element
std::nth_element(vec.begin(), vec.begin() + 2, vec.end());// binary_search (需要有序序列)
bool found = std::binary_search(vec.begin(), vec.end(), 3);// lower_bound, upper_bound
auto lower = std::lower_bound(vec.begin(), vec.end(), 3);
auto upper = std::upper_bound(vec.begin(), vec.end(), 3);// 数值算法
#include <numeric>// accumulate
int sum = std::accumulate(vec.begin(), vec.end(), 0);// inner_product
int dotProduct = std::inner_product(vec.begin(), vec.end(), vec2.begin(), 0);// adjacent_difference
std::adjacent_difference(vec.begin(), vec.end(), vec2.begin());// partial_sum
std::partial_sum(vec.begin(), vec.end(), vec2.begin());
5.4 函数对象与Lambda
// 函数对象(仿函数)
struct Multiply {int factor;Multiply(int f) : factor(f) {}int operator()(int x) const {return x * factor;}
};std::vector<int> vec = {1, 2, 3, 4, 5};
std::transform(vec.begin(), vec.end(), vec.begin(), Multiply(2));// 标准函数对象
std::sort(vec.begin(), vec.end(), std::greater<int>());// Lambda表达式 (C++11)
// [捕获列表](参数列表) -> 返回类型 { 函数体 }int factor = 2;
auto multiply = [factor](int x) { return x * factor; };// 捕获方式
// [=] - 按值捕获所有外部变量
// [&] - 按引用捕获所有外部变量
// [x] - 按值捕获x
// [&x] - 按引用捕获x
// [=, &x] - 按值捕获所有,但x按引用
// [&, x] - 按引用捕获所有,但x按值// mutable lambda
int count = 0;
auto counter = [count]() mutable { return ++count; };// 泛型lambda (C++14)
auto genericLambda = [](auto x, auto y) { return x + y; };// std::function
std::function<int(int, int)> func = [](int a, int b) { return a + b; };
6. 现代 C++ 特性
6.1 C++11 特性
// auto类型推导
auto x = 42;
auto y = 3.14;
auto str = std::string("hello");// decltype
int a = 0;
decltype(a) b = 1; // b的类型是int
decltype((a)) c = a; // c的类型是int&// nullptr
int* p = nullptr;// 范围for循环
std::vector<int> vec = {1, 2, 3, 4, 5};
for (const auto& elem : vec) {std::cout << elem << " ";
}// 初始化列表
std::vector<int> v = {1, 2, 3, 4, 5};
std::map<std::string, int> m = {{"a", 1}, {"b", 2}};// 统一初始化
int arr[]{1, 2, 3};
std::vector<int> v{1, 2, 3};
MyClass obj{1, 2, 3};// 右值引用和移动语义
class Buffer {
private:size_t size;int* data;public:// 移动构造函数Buffer(Buffer&& other) noexcept: size(other.size), data(other.data) {other.size = 0;other.data = nullptr;}// 移动赋值运算符Buffer& operator=(Buffer&& other) noexcept {if (this != &other) {delete[] data;size = other.size;data = other.data;other.size = 0;other.data = nullptr;}return *this;}
};// 完美转发
template<typename T>
void wrapper(T&& arg) {func(std::forward<T>(arg));
}// constexpr
constexpr int factorial(int n) {return n <= 1 ? 1 : n * factorial(n - 1);
}// 委托构造函数
class MyClass {int a, b, c;
public:MyClass(int x) : MyClass(x, 0, 0) {}MyClass(int x, int y) : MyClass(x, y, 0) {}MyClass(int x, int y, int z) : a(x), b(y), c(z) {}
};// 继承构造函数
class Base {
public:Base(int x) {}Base(int x, int y) {}
};class Derived : public Base {using Base::Base; // 继承所有构造函数
};// override和final
class Base {virtual void func() {}virtual void func2() final {} // 不能被重写
};class Derived : public Base {void func() override {} // 明确表示重写// void func2() override {} // 错误
};class FinalClass final {}; // 不能被继承// default和delete
class MyClass {
public:MyClass() = default; // 使用编译器生成的默认构造函数MyClass(const MyClass&) = delete; // 禁用拷贝构造函数
};// static_assert
static_assert(sizeof(int) == 4, "int must be 4 bytes");// noexcept
void func() noexcept {// 保证不抛出异常
}// alignof和alignas
struct alignas(16) AlignedStruct {char data[10];
};
static_assert(alignof(AlignedStruct) == 16);// 原始字符串字面值
const char* regex = R"(\w+@\w+\.\w+)";
const char* multiline = R"(Line 1
Line 2
Line 3)";// 用户定义字面值
constexpr long double operator"" _deg(long double deg) {return deg * 3.14159 / 180;
}
double angle = 90.0_deg;// 变参模板
template<typename... Args>
void print(Args... args) {((std::cout << args << " "), ...);
}// tuple
std::tuple<int, double, std::string> t(1, 3.14, "hello");
int x = std::get<0>(t);
auto [a, b, c] = t; // C++17 结构化绑定// 智能指针
std::unique_ptr<int> up = std::make_unique<int>(42);
std::shared_ptr<int> sp = std::make_shared<int>(42);// 线程支持
std::thread t([]{ std::cout << "Hello from thread\n"; });
t.join();// atomic
std::atomic<int> counter(0);
counter.fetch_add(1);// chrono
auto start = std::chrono::high_resolution_clock::now();
// ... 代码 ...
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
6.2 C++14 特性
// 泛型lambda
auto genericLambda = [](auto x, auto y) { return x + y;
};// 初始化捕获
int x = 4;
auto lambda = [value = x + 1]{ return value; };// 返回类型推导
auto func() {return 42; // 返回类型推导为int
}// decltype(auto)
decltype(auto) func2() {int x = 0;return (x); // 返回int&
}// 放松constexpr限制
constexpr int factorial(int n) {int result = 1;for (int i = 1; i <= n; ++i) {result *= i;}return result;
}// 变量模板
template<typename T>
constexpr T pi = T(3.14159265358979323846);double area = pi<double> * r * r;// 二进制字面值
int binary = 0b1010; // 10// 数字分隔符
long long big = 1'000'000'000;
int binary2 = 0b1010'1010;// [[deprecated]]属性
[[deprecated("Use newFunc instead")]]
void oldFunc() {}// std::make_unique
auto up = std::make_unique<int>(42);
6.3 C++17 特性
// 结构化绑定
std::pair<int, std::string> p = {1, "hello"};
auto [id, name] = p;std::map<int, std::string> m = {{1, "one"}, {2, "two"}};
for (const auto& [key, value] : m) {std::cout << key << ": " << value << "\n";
}// if/switch初始化语句
if (auto it = m.find(1); it != m.end()) {std::cout << "Found: " << it->second << "\n";
}// constexpr if
template<typename T>
auto getValue(T t) {if constexpr (std::is_pointer_v<T>) {return *t;} else {return t;}
}// 折叠表达式
template<typename... Args>
auto sum(Args... args) {return (args + ...); // 右折叠
}template<typename... Args>
void print(Args... args) {((std::cout << args << " "), ...);
}// inline变量
inline int globalVar = 42;// std::optional
std::optional<int> divide(int a, int b) {if (b == 0) return std::nullopt;return a / b;
}auto result = divide(10, 2);
if (result) {std::cout << "Result: " << *result << "\n";
}// std::variant
std::variant<int, double, std::string> v = "hello";
std::visit([](auto&& arg) {using T = std::decay_t<decltype(arg)>;if constexpr (std::is_same_v<T, int>) {std::cout << "int: " << arg << "\n";} else if constexpr (std::is_same_v<T, double>) {std::cout << "double: " << arg << "\n";} else {std::cout << "string: " << arg << "\n";}
}, v);// std::any
std::any a = 42;
a = std::string("hello");
if (a.has_value()) {try {std::cout << std::any_cast<std::string>(a) << "\n";} catch (const std::bad_any_cast& e) {std::cout << e.what() << "\n";}
}// std::string_view
void processString(std::string_view sv) {std::cout << sv << "\n";
}// std::filesystem
#include <filesystem>
namespace fs = std::filesystem;for (const auto& entry : fs::directory_iterator(".")) {std::cout << entry.path() << "\n";
}// 并行算法
std::vector<int> v = {3, 1, 4, 1, 5, 9};
std::sort(std::execution::par, v.begin(), v.end());// std::byte
std::byte b{42};
std::byte b2 = b << 1;// 类模板参数推导
std::pair p(1, 3.14); // pair<int, double>
std::vector v = {1, 2, 3}; // vector<int>// [[nodiscard]]属性
[[nodiscard]] int computeValue() { return 42; }
// computeValue(); // 警告:忽略返回值// [[fallthrough]]属性
switch (x) {case 1:doSomething();[[fallthrough]];case 2:doSomethingElse();break;
}// [[maybe_unused]]属性
[[maybe_unused]] int unusedVar = 42;
6.4 C++20 特性
// 概念(Concepts)
template<typename T>
concept Integral = std::is_integral_v<T>;template<Integral T>
T add(T a, T b) {return a + b;
}// 范围(Ranges)
#include <ranges>std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto result = v | std::views::filter([](int n) { return n % 2 == 0; })| std::views::transform([](int n) { return n * n; });// 协程(Coroutines)
#include <coroutine>struct Generator {struct promise_type {int current_value;auto initial_suspend() { return std::suspend_always{}; }auto final_suspend() noexcept { return std::suspend_always{}; }auto get_return_object() { return Generator{this}; }void return_void() {}void unhandled_exception() {}auto yield_value(int value) {current_value = value;return std::suspend_always{};}};using handle_type = std::coroutine_handle<promise_type>;handle_type coro;Generator(promise_type* p) : coro(handle_type::from_promise(*p)) {}~Generator() {if (coro) coro.destroy();}int getValue() {coro.resume();return coro.promise().current_value;}
};Generator fibonacci() {int a = 0, b = 1;while (true) {co_yield a;auto tmp = a;a = b;b = tmp + b;}
}// 模块(Modules)
// module.ixx
export module math;
export int add(int a, int b) { return a + b; }// main.cpp
import math;
int result = add(1, 2);// 三向比较运算符
#include <compare>struct Point {int x, y;auto operator<=>(const Point&) const = default;
};Point p1{1, 2}, p2{1, 3};
if (p1 < p2) { /* ... */ }// 指定初始化器
struct Point {int x, y, z;
};
Point p{.x = 1, .z = 3}; // y = 0// consteval - 立即函数
consteval int sqr(int n) {return n * n;
}
constexpr int r = sqr(5); // OK
// int x = 5;
// int y = sqr(x); // 错误:x不是常量表达式// constinit
constinit int g = 42; // 保证常量初始化// char8_t
char8_t utf8_char = u8'a';
const char8_t* utf8_string = u8"Hello";// [[likely]]和[[unlikely]]
int value = getValue();
if (value > 0) [[likely]] {// 更可能执行的分支
} else [[unlikely]] {// 不太可能执行的分支
}// std::span
void processArray(std::span<int> arr) {for (int x : arr) {std::cout << x << " ";}
}int arr[] = {1, 2, 3, 4, 5};
processArray(arr);// std::format
#include <format>
std::string s = std::format("The answer is {}.", 42);// std::jthread
std::jthread t([]{ std::cout << "Hello from jthread\n";
});
// 自动join// std::latch和std::barrier
std::latch latch(3);
// 线程中:
latch.count_down();
latch.wait();// std::source_location
#include <source_location>
void log(const std::string& message,const std::source_location& loc = std::source_location::current()) {std::cout << loc.file_name() << ":"<< loc.line() << " "<< message << "\n";
}
7. 设计模式
7.1 创建型模式
单例模式
// 懒汉式单例(线程安全)
class Singleton {
private:static Singleton* instance;static std::mutex mtx;Singleton() {}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;public:static Singleton* getInstance() {// 双重检查锁定if (instance == nullptr) {std::lock_guard<std::mutex> lock(mtx);if (instance == nullptr) {instance = new Singleton();}}return instance;}
};Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;// C++11 静态局部变量(推荐)
class Singleton {
private:Singleton() {}
public:static Singleton& getInstance() {static Singleton instance; // C++11保证线程安全return instance;}Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;
};
工厂模式
// 简单工厂
class Product {
public:virtual ~Product() {}virtual void use() = 0;
};class ConcreteProductA : public Product {
public:void use() override {std::cout << "Using Product A\n";}
};class ConcreteProductB : public Product {
public:void use() override {std::cout << "Using Product B\n";}
};class SimpleFactory {
public:static std::unique_ptr<Product> createProduct(const std::string& type) {if (type == "A") {return std::make_unique<ConcreteProductA>();} else if (type == "B") {return std::make_unique<ConcreteProductB>();}return nullptr;}
};// 工厂方法模式
class Factory {
public:virtual ~Factory() {}virtual std::unique_ptr<Product> createProduct() = 0;
};class ConcreteFactoryA : public Factory {
public:std::unique_ptr<Product> createProduct() override {return std::make_unique<ConcreteProductA>();}
};// 抽象工厂模式
class AbstractFactory {
public:virtual ~AbstractFactory() {}virtual std::unique_ptr<ProductA> createProductA() = 0;virtual std::unique_ptr<ProductB> createProductB() = 0;
};class ConcreteFactory1 : public AbstractFactory {
public:std::unique_ptr<ProductA> createProductA() override {return std::make_unique<ProductA1>();}std::unique_ptr<ProductB> createProductB() override {return std::make_unique<ProductB1>();}
};
建造者模式
class Product {
public:void setPartA(const std::string& part) { partA = part; }void setPartB(const std::string& part) { partB = part; }void setPartC(const std::string& part) { partC = part; }void show() {std::cout << "Product: " << partA << ", " << partB << ", " << partC << "\n";}
private:std::string partA, partB, partC;
};class Builder {
public:virtual ~Builder() {}virtual void buildPartA() = 0;virtual void buildPartB() = 0;virtual void buildPartC() = 0;virtual std::unique_ptr<Product> getResult() = 0;
};class ConcreteBuilder : public Builder {
private:std::unique_ptr<Product> product;
public:ConcreteBuilder() : product(std::make_unique<Product>()) {}void buildPartA() override {product->setPartA("Part A");}void buildPartB() override {product->setPartB("Part B");}void buildPartC() override {product->setPartC("Part C");}std::unique_ptr<Product> getResult() override {return std::move(product);}
};class Director {
private:Builder* builder;
public:void setBuilder(Builder* b) { builder = b; }void construct() {builder->buildPartA();builder->buildPartB();builder->buildPartC();}
};
7.2 结构型模式
适配器模式
// 类适配器(多继承)
class Target {
public:virtual ~Target() {}virtual void request() = 0;
};class Adaptee {
public:void specificRequest() {std::cout << "Specific request\n";}
};class ClassAdapter : public Target, private Adaptee {
public:void request() override {specificRequest();}
};// 对象适配器(组合)
class ObjectAdapter : public Target {
private:std::unique_ptr<Adaptee> adaptee;
public:ObjectAdapter() : adaptee(std::make_unique<Adaptee>()) {}void request() override {adaptee->specificRequest();}
};
装饰器模式
class Component {
public:virtual ~Component() {}virtual void operation() = 0;
};class ConcreteComponent : public Component {
public:void operation() override {std::cout << "ConcreteComponent operation\n";}
};class Decorator : public Component {
protected:std::unique_ptr<Component> component;
public:Decorator(std::unique_ptr<Component> comp) : component(std::move(comp)) {}void operation() override {if (component) {component->operation();}}
};class ConcreteDecoratorA : public Decorator {
public:ConcreteDecoratorA(std::unique_ptr<Component> comp) : Decorator(std::move(comp)) {}void operation() override {Decorator::operation();addedBehavior();}private:void addedBehavior() {std::cout << "ConcreteDecoratorA added behavior\n";}
};// 使用
auto component = std::make_unique<ConcreteComponent>();
auto decorated = std::make_unique<ConcreteDecoratorA>(std::move(component));
decorated->operation();
代理模式
class Subject {
public:virtual ~Subject() {}virtual void request() = 0;
};class RealSubject : public Subject {
public:void request() override {std::cout << "RealSubject request\n";}
};class Proxy : public Subject {
private:std::unique_ptr<RealSubject> realSubject;public:void request() override {if (!realSubject) {realSubject = std::make_unique<RealSubject>();}preRequest();realSubject->request();postRequest();}private:void preRequest() {std::cout << "Proxy pre-request\n";}void postRequest() {std::cout << "Proxy post-request\n";}
};
7.3 行为型模式
观察者模式
class Observer {
public:virtual ~Observer() {}virtual void update(int state) = 0;
};class Subject {
private:std::vector<std::weak_ptr<Observer>> observers;int state;public:void attach(std::shared_ptr<Observer> observer) {observers.push_back(observer);}void detach(std::shared_ptr<Observer> observer) {observers.erase(std::remove_if(observers.begin(), observers.end(),[&observer](const std::weak_ptr<Observer>& weak) {auto shared = weak.lock();return !shared || shared == observer;}),observers.end());}void notify() {for (auto it = observers.begin(); it != observers.end();) {if (auto observer = it->lock()) {observer->update(state);++it;} else {it = observers.erase(it);}}}void setState(int s) {state = s;notify();}
};class ConcreteObserver : public Observer {
private:std::string name;public:ConcreteObserver(const std::string& n) : name(n) {}void update(int state) override {std::cout << name << " received update: " << state << "\n";}
};
策略模式
class Strategy {
public:virtual ~Strategy() {}virtual int execute(int a, int b) = 0;
};class AddStrategy : public Strategy {
public:int execute(int a, int b) override {return a + b;}
};class MultiplyStrategy : public Strategy {
public:int execute(int a, int b) override {return a * b;}
};class Context {
private:std::unique_ptr<Strategy> strategy;public:void setStrategy(std::unique_ptr<Strategy> s) {strategy = std::move(s);}int executeStrategy(int a, int b) {if (strategy) {return strategy->execute(a, b);}return 0;}
};// 使用
Context context;
context.setStrategy(std::make_unique<AddStrategy>());
int result = context.executeStrategy(5, 3); // 8
命令模式
class Command {
public:virtual ~Command() {}virtual void execute() = 0;virtual void undo() = 0;
};class Light {
public:void on() { std::cout << "Light is on\n"; }void off() { std::cout << "Light is off\n"; }
};class LightOnCommand : public Command {
private:Light* light;public:LightOnCommand(Light* l) : light(l) {}void execute() override {light->on();}void undo() override {light->off();}
};class RemoteControl {
private:std::unique_ptr<Command> command;std::stack<std::unique_ptr<Command>> history;public:void setCommand(std::unique_ptr<Command> cmd) {command = std::move(cmd);}void pressButton() {if (command) {command->execute();// history.push(std::move(command)); // 保存历史}}void pressUndo() {if (command) {command->undo();}}
};
8. 性能优化
8.1 编译器优化
// 编译器优化级别
// -O0: 无优化
// -O1: 基本优化
// -O2: 更多优化(推荐)
// -O3: 激进优化
// -Os: 优化大小
// -Ofast: 最快速度(可能不符合标准)// 内联优化
inline int add(int a, int b) { return a + b; }// 强制内联(编译器特定)
__forceinline int multiply(int a, int b) { return a * b; } // MSVC
__attribute__((always_inline)) int divide(int a, int b); // GCC/Clang// 循环展开
// 手动展开
for (int i = 0; i < n; i += 4) {a[i] = b[i] + c[i];a[i+1] = b[i+1] + c[i+1];a[i+2] = b[i+2] + c[i+2];a[i+3] = b[i+3] + c[i+3];
}// 编译器提示
#pragma GCC optimize("unroll-loops")// 向量化
// 编译器自动向量化
#pragma GCC optimize("tree-vectorize")// 手动SIMD
#include <immintrin.h>
void add_vectors(float* a, float* b, float* c, int n) {for (int i = 0; i < n; i += 8) {__m256 va = _mm256_load_ps(&a[i]);__m256 vb = _mm256_load_ps(&b[i]);__m256 vc = _mm256_add_ps(va, vb);_mm256_store_ps(&c[i], vc);}
}
8.2 内存优化
// 内存对齐
struct alignas(64) CacheLinePadded {std::atomic<int> value;char padding[60]; // 避免伪共享
};// 结构体成员排序(减少内存占用)
// 错误示例
struct Bad {char a; // 1 byteint b; // 4 bytes (3 bytes padding)char c; // 1 byte (3 bytes padding)// Total: 12 bytes
};// 正确示例
struct Good {int b; // 4 byteschar a; // 1 bytechar c; // 1 byte (2 bytes padding)// Total: 8 bytes
};// 内存池
template<typename T>
class ObjectPool {
private:std::stack<std::unique_ptr<T>> pool;public:std::unique_ptr<T> acquire() {if (pool.empty()) {return std::make_unique<T>();}std::unique_ptr<T> obj = std::move(pool.top());pool.pop();return obj;}void release(std::unique_ptr<T> obj) {pool.push(std::move(obj));}
};// 预分配
std::vector<int> vec;
vec.reserve(1000); // 预分配空间// 使用emplace_back代替push_back
vec.emplace_back(42); // 原地构造,避免拷贝// 移动语义优化
std::vector<std::string> data;
std::string str = "Hello";
data.push_back(std::move(str)); // 使用移动而非拷贝
8.3 算法优化
// 缓存友好的算法
// 行优先遍历(缓存友好)
for (int i = 0; i < rows; ++i) {for (int j = 0; j < cols; ++j) {matrix[i][j] = 0;}
}// 列优先遍历(缓存不友好)
for (int j = 0; j < cols; ++j) {for (int i = 0; i < rows; ++i) {matrix[i][j] = 0;}
}// 分支预测优化
// 使用likely/unlikely提示
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)if (likely(condition)) {// 更可能执行的分支
} else {// 不太可能执行的分支
}// 循环优化
// 减少循环内的计算
int factor = a * b;
for (int i = 0; i < n; ++i) {result[i] = data[i] * factor; // factor在循环外计算
}// 使用查找表
const int sin_table[360] = { /* 预计算的值 */ };
int sin_degree(int degree) {return sin_table[degree % 360];
}// 尾递归优化
int factorial_tail(int n, int accumulator = 1) {if (n <= 1) return accumulator;return factorial_tail(n - 1, n * accumulator);
}
8.4 并行优化
// 使用OpenMP
#include <omp.h>void parallel_add(float* a, float* b, float* c, int n) {#pragma omp parallel forfor (int i = 0; i < n; ++i) {c[i] = a[i] + b[i];}
}// 使用std::execution (C++17)
std::vector<int> vec(1000000);
std::sort(std::execution::par_unseq, vec.begin(), vec.end());// 任务并行
#include <future>auto future1 = std::async(std::launch::async, []{ return compute1(); });
auto future2 = std::async(std::launch::async, []{ return compute2(); });
auto result1 = future1.get();
auto result2 = future2.get();// 无锁编程
template<typename T>
class LockFreeQueue {
private:struct Node {std::atomic<T*> data;std::atomic<Node*> next;Node() : data(nullptr), next(nullptr) {}};std::atomic<Node*> head;std::atomic<Node*> tail;public:LockFreeQueue() {Node* dummy = new Node;head.store(dummy);tail.store(dummy);}void enqueue(T item) {Node* newNode = new Node;T* data = new T(std::move(item));newNode->data.store(data);while (true) {Node* last = tail.load();Node* next = last->next.load();if (last == tail.load()) {if (next == nullptr) {if (last->next.compare_exchange_weak(next, newNode)) {tail.compare_exchange_weak(last, newNode);break;}} else {tail.compare_exchange_weak(last, next);}}}}
};
8.5 性能分析工具
// 简单的性能计时
#include <chrono>class Timer {
private:std::chrono::high_resolution_clock::time_point start;public:Timer() : start(std::chrono::high_resolution_clock::now()) {}double elapsed() const {auto end = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);return duration.count() / 1000.0; // 返回毫秒}
};// 使用
{Timer timer;// 执行代码double ms = timer.elapsed();std::cout << "Elapsed: " << ms << " ms\n";
}// 性能分析工具
// 1. gprof (Linux)
// 2. Valgrind (Linux)
// 3. Intel VTune
// 4. AMD CodeXL
// 5. Visual Studio Profiler
// 6. perf (Linux)
9. 多线程与并发
9.1 线程基础
#include <thread>
#include <iostream>// 创建线程
void threadFunction(int id) {std::cout << "Thread " << id << " is running\n";
}int main() {std::thread t1(threadFunction, 1);std::thread t2(threadFunction, 2);t1.join(); // 等待线程结束t2.join();// Lambda表达式std::thread t3([](int x) {std::cout << "Lambda thread: " << x << "\n";}, 42);t3.join();// 传递引用参数int value = 10;std::thread t4([](int& v) { v++; }, std::ref(value));t4.join();return 0;
}// 线程管理
class ThreadGuard {
private:std::thread& t;
public:explicit ThreadGuard(std::thread& t_) : t(t_) {}~ThreadGuard() {if (t.joinable()) {t.join();}}ThreadGuard(const ThreadGuard&) = delete;ThreadGuard& operator=(const ThreadGuard&) = delete;
};// 使用
void func() {std::thread t(threadFunction, 1);ThreadGuard g(t);// 即使抛出异常,线程也会被正确join
}
9.2 互斥量与锁
#include <mutex>// 基本互斥量
std::mutex mtx;
int shared_data = 0;void safe_increment() {std::lock_guard<std::mutex> lock(mtx);++shared_data;
} // 自动解锁// unique_lock - 更灵活
void flexible_lock() {std::unique_lock<std::mutex> lock(mtx);// 可以手动解锁和重新锁定lock.unlock();// 做一些不需要锁的操作lock.lock();
}// 递归互斥量
std::recursive_mutex rec_mtx;void recursive_function(int count) {std::lock_guard<std::recursive_mutex> lock(rec_mtx);if (count > 0) {recursive_function(count - 1);}
}// 读写锁 (C++17)
#include <shared_mutex>std::shared_mutex rw_mtx;
int data = 0;void reader() {std::shared_lock<std::shared_mutex> lock(rw_mtx);// 多个线程可以同时读int local = data;
}void writer() {std::unique_lock<std::shared_mutex> lock(rw_mtx);// 独占写data = 42;
}// 避免死锁
std::mutex mtx1, mtx2;void avoid_deadlock() {// 同时锁定多个互斥量,避免死锁std::scoped_lock lock(mtx1, mtx2); // C++17// 或者使用 std::lock (C++11)std::unique_lock<std::mutex> lock1(mtx1, std::defer_lock);std::unique_lock<std::mutex> lock2(mtx2, std::defer_lock);std::lock(lock1, lock2);
}
9.3 条件变量
#include <condition_variable>
#include <queue>// 生产者-消费者模型
template<typename T>
class ThreadSafeQueue {
private:mutable std::mutex mtx;std::queue<T> queue;std::condition_variable cv;public:void push(T value) {{std::lock_guard<std::mutex> lock(mtx);queue.push(std::move(value));}cv.notify_one();}void wait_and_pop(T& value) {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, [this] { return !queue.empty(); });value = std::move(queue.front());queue.pop();}bool try_pop(T& value) {std::lock_guard<std::mutex> lock(mtx);if (queue.empty()) {return false;}value = std::move(queue.front());queue.pop();return true;}bool empty() const {std::lock_guard<std::mutex> lock(mtx);return queue.empty();}
};// 使用条件变量实现信号量
class Semaphore {
private:std::mutex mtx;std::condition_variable cv;int count;public:explicit Semaphore(int count_ = 0) : count(count_) {}void notify() {std::unique_lock<std::mutex> lock(mtx);++count;cv.notify_one();}void wait() {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, [this] { return count > 0; });--count;}bool try_wait() {std::lock_guard<std::mutex> lock(mtx);if (count > 0) {--count;return true;}return false;}
};
9.4 原子操作
#include <atomic>// 基本原子类型
std::atomic<int> counter(0);void increment() {counter.fetch_add(1, std::memory_order_relaxed);
}// 自定义原子类型
struct Point { int x, y; };
std::atomic<Point> atomicPoint;// 原子标志
std::atomic_flag flag = ATOMIC_FLAG_INIT;void spinlock_example() {// 自旋锁while (flag.test_and_set(std::memory_order_acquire)) {// 自旋等待}// 临界区flag.clear(std::memory_order_release);
}// 内存序
// memory_order_relaxed: 最弱的顺序保证
// memory_order_acquire: 读操作,之后的读写不能重排到此操作之前
// memory_order_release: 写操作,之前的读写不能重排到此操作之后
// memory_order_acq_rel: 同时具有acquire和release语义
// memory_order_seq_cst: 顺序一致性(默认)// 无锁编程示例
template<typename T>
class LockFreeStack {
private:struct Node {T data;Node* next;Node(T data_) : data(std::move(data_)), next(nullptr) {}};std::atomic<Node*> head;public:LockFreeStack() : head(nullptr) {}~LockFreeStack() {while (Node* oldHead = head.load()) {head.store(oldHead->next);delete oldHead;}}void push(T data) {Node* newNode = new Node(std::move(data));newNode->next = head.load(std::memory_order_relaxed);while (!head.compare_exchange_weak(newNode->next, newNode,std::memory_order_release,std::memory_order_relaxed)) {// 循环直到成功}}bool pop(T& result) {Node* oldHead = head.load(std::memory_order_relaxed);while (oldHead && !head.compare_exchange_weak(oldHead, oldHead->next,std::memory_order_acquire,std::memory_order_relaxed)) {// 循环直到成功或栈为空}if (oldHead) {result = std::move(oldHead->data);delete oldHead;return true;}return false;}
};
9.5 并发工具
#include <future>
#include <functional>// future和promise
void use_future() {std::promise<int> promise;std::future<int> future = promise.get_future();std::thread t([](std::promise<int> p) {// 模拟计算std::this_thread::sleep_for(std::chrono::seconds(1));p.set_value(42);}, std::move(promise));// 获取结果int result = future.get();t.join();
}// async
void use_async() {auto future = std::async(std::launch::async, []() {std::this_thread::sleep_for(std::chrono::seconds(1));return 42;});// 做其他事情...int result = future.get();
}// packaged_task
void use_packaged_task() {std::packaged_task<int(int, int)> task([](int a, int b) {return a + b;});auto future = task.get_future();std::thread t(std::move(task), 5, 3);int result = future.get(); // 8t.join();
}// shared_future
void use_shared_future() {std::promise<int> promise;std::shared_future<int> future = promise.get_future().share();// 多个线程可以访问同一个shared_futurestd::vector<std::thread> threads;for (int i = 0; i < 5; ++i) {threads.emplace_back([future, i]() {int result = future.get();std::cout << "Thread " << i << " got: " << result << "\n";});}promise.set_value(42);for (auto& t : threads) {t.join();}
}// 线程池实现
class ThreadPool {
private:std::vector<std::thread> workers;std::queue<std::function<void()>> tasks;std::mutex queue_mutex;std::condition_variable condition;bool stop = false;public:ThreadPool(size_t threads) {for (size_t i = 0; i < threads; ++i) {workers.emplace_back([this] {while (true) {std::function<void()> task;{std::unique_lock<std::mutex> lock(queue_mutex);condition.wait(lock, [this] { return stop || !tasks.empty(); });if (stop && tasks.empty()) {return;}task = std::move(tasks.front());tasks.pop();}task();}});}}template<typename F, typename... Args>auto enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type> {using return_type = typename std::result_of<F(Args...)>::type;auto task = std::make_shared<std::packaged_task<return_type()>>(std::bind(std::forward<F>(f), std::forward<Args>(args)...));std::future<return_type> res = task->get_future();{std::unique_lock<std::mutex> lock(queue_mutex);if (stop) {throw std::runtime_error("enqueue on stopped ThreadPool");}tasks.emplace([task]() { (*task)(); });}condition.notify_one();return res;}~ThreadPool() {{std::unique_lock<std::mutex> lock(queue_mutex);stop = true;}condition.notify_all();for (std::thread& worker : workers) {worker.join();}}
};
10. 编译与链接
10.1 编译过程
// 编译过程:预处理 -> 编译 -> 汇编 -> 链接// 1. 预处理
// g++ -E main.cpp -o main.i
#define MAX 100
#include <iostream>// 2. 编译
// g++ -S main.i -o main.s
// 生成汇编代码// 3. 汇编
// g++ -c main.s -o main.o
// 生成目标文件// 4. 链接
// g++ main.o -o main
// 生成可执行文件// 查看符号表
// nm main.o// 查看依赖库
// ldd main// 查看段信息
// objdump -h main
10.2 链接类型
// 静态链接
// g++ main.cpp -static -o main// 动态链接(默认)
// g++ main.cpp -o main// 创建静态库
// ar rcs libmylib.a file1.o file2.o// 使用静态库
// g++ main.cpp -L. -lmylib -o main// 创建动态库
// g++ -shared -fPIC file1.cpp file2.cpp -o libmylib.so// 使用动态库
// g++ main.cpp -L. -lmylib -o main
// export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
10.3 符号可见性
// 控制符号可见性
#ifdef _WIN32#ifdef BUILDING_DLL#define API __declspec(dllexport)#else#define API __declspec(dllimport)#endif
#else#define API __attribute__((visibility("default")))
#endifclass API MyClass {
public:void publicMethod();private:void privateMethod();
};// 隐藏符号
__attribute__((visibility("hidden"))) void hiddenFunction() {}// 编译选项
// g++ -fvisibility=hidden -fvisibility-inlines-hidden
10.4 模板实例化
// 隐式实例化
template<typename T>
T max(T a, T b) { return a > b ? a : b; }// 使用时自动实例化
int m = max(1, 2);// 显式实例化声明
extern template class std::vector<int>;// 显式实例化定义
template class std::vector<int>;// 函数模板显式实例化
template int max<int>(int, int);// 避免模板代码膨胀
// 1. 使用extern template
// 2. 将模板实现放在.cpp文件中并显式实例化
// 3. 使用类型擦除技术
11. 常见面试题
11.1 语言特性相关
1. 指针和引用的区别?
// 主要区别:
// 1. 引用必须初始化,指针可以不初始化
// 2. 引用不能为NULL,指针可以为NULL
// 3. 引用不能改变指向,指针可以
// 4. 没有引用数组,但有指针数组
// 5. 没有多级引用,但有多级指针
// 6. sizeof结果不同int a = 10;
int& ref = a; // 引用必须初始化
int* ptr; // 指针可以不初始化
ptr = &a;// ref = b; // 错误:引用不能改变指向
ptr = &b; // 正确:指针可以改变指向sizeof(ref); // 返回int的大小
sizeof(ptr); // 返回指针的大小
2. const的用法?
// 1. 常量
const int MAX = 100;// 2. 指针和const
const int* p1; // 指向常量的指针
int const* p2; // 同上
int* const p3 = &a; // 常量指针
const int* const p4 = &a; // 指向常量的常量指针// 3. 函数参数
void func(const std::string& str); // 避免拷贝,不修改// 4. 成员函数
class MyClass {void getValue() const; // 不修改成员变量
};// 5. 返回值
const std::string& getName() const { return name; }
3. static的用法?
// 1. 静态局部变量
void func() {static int count = 0; // 只初始化一次count++;
}// 2. 静态全局变量/函数(内部链接)
static int global_var = 0;
static void helper_func() {}// 3. 类的静态成员
class MyClass {static int count; // 声明static void staticFunc(); // 不能访问非静态成员
};
int MyClass::count = 0; // 定义// 4. 静态成员函数
MyClass::staticFunc(); // 通过类名调用
4. 虚函数的实现原理?
// 虚函数通过虚函数表(vtable)实现
class Base {
public:virtual void func1() {}virtual void func2() {}
};// 编译器生成的结构(简化):
// Base对象内存布局:
// [vptr] -> 指向虚函数表
// [成员变量]// 虚函数表布局:
// [0] -> Base::func1()
// [1] -> Base::func2()class Derived : public Base {
public:void func1() override {} // 覆盖虚函数表中的条目
};// 动态绑定过程:
Base* ptr = new Derived();
ptr->func1(); // 通过vptr找到虚函数表,调用正确的函数
5. 什么是RAII?
// Resource Acquisition Is Initialization
// 资源获取即初始化class FileWrapper {
private:FILE* file;
public:FileWrapper(const char* filename) {file = fopen(filename, "r");if (!file) throw std::runtime_error("Failed to open file");}~FileWrapper() {if (file) fclose(file);}// 禁止拷贝FileWrapper(const FileWrapper&) = delete;FileWrapper& operator=(const FileWrapper&) = delete;
};// 使用:
{FileWrapper fw("data.txt");// 使用文件
} // 自动关闭文件,即使发生异常
11.2 内存相关
1. 内存泄漏如何检测和避免?
// 检测方法:
// 1. 使用工具:Valgrind, AddressSanitizer
// 2. 重载new/delete
// 3. 智能指针// 避免方法:
// 1. 使用RAII
// 2. 使用智能指针
std::unique_ptr<int> p1 = std::make_unique<int>(42);
std::shared_ptr<int> p2 = std::make_shared<int>(42);// 3. 遵循规则
// - 谁申请谁释放
// - 使用容器管理动态数组
// - 避免裸指针// 4. 自定义内存管理
class MemoryTracker {static std::unordered_map<void*, size_t> allocations;
public:static void* allocate(size_t size) {void* ptr = malloc(size);allocations[ptr] = size;return ptr;}static void deallocate(void* ptr) {allocations.erase(ptr);free(ptr);}static void checkLeaks() {if (!allocations.empty()) {std::cout << "Memory leaks detected!\n";for (const auto& [ptr, size] : allocations) {std::cout << "Leaked " << size << " bytes at " << ptr << "\n";}}}
};
2. new/malloc的区别?
// 主要区别:
// 1. new是运算符,malloc是函数
// 2. new调用构造函数,malloc不调用
// 3. new返回对象指针,malloc返回void*
// 4. new失败抛异常,malloc返回NULL
// 5. new可以重载,malloc不能
// 6. new/delete配对,malloc/free配对// new的过程:
// 1. 调用operator new分配内存
// 2. 调用构造函数
// 3. 返回对象指针class MyClass {int data;
public:MyClass(int d) : data(d) {std::cout << "Constructor\n";}
};// 使用new
MyClass* p1 = new MyClass(42); // 分配内存+构造
delete p1; // 析构+释放内存// 使用malloc
MyClass* p2 = (MyClass*)malloc(sizeof(MyClass)); // 只分配内存
new (p2) MyClass(42); // placement new构造
p2->~MyClass(); // 手动析构
free(p2); // 释放内存
3. 智能指针的实现原理?
// 简化版unique_ptr实现
template<typename T>
class UniquePtr {
private:T* ptr;public:explicit UniquePtr(T* p = nullptr) : ptr(p) {}~UniquePtr() {delete ptr;}// 禁止拷贝UniquePtr(const UniquePtr&) = delete;UniquePtr& operator=(const UniquePtr&) = delete;// 移动构造UniquePtr(UniquePtr&& other) noexcept : ptr(other.ptr) {other.ptr = nullptr;}// 移动赋值UniquePtr& operator=(UniquePtr&& other) noexcept {if (this != &other) {delete ptr;ptr = other.ptr;other.ptr = nullptr;}return *this;}T& operator*() const { return *ptr; }T* operator->() const { return ptr; }T* get() const { return ptr; }T* release() {T* temp = ptr;ptr = nullptr;return temp;}void reset(T* p = nullptr) {delete ptr;ptr = p;}
};// 简化版shared_ptr实现
template<typename T>
class SharedPtr {
private:T* ptr;size_t* ref_count;public:explicit SharedPtr(T* p = nullptr) : ptr(p), ref_count(p ? new size_t(1) : nullptr) {}SharedPtr(const SharedPtr& other) : ptr(other.ptr), ref_count(other.ref_count) {if (ref_count) {++(*ref_count);}}~SharedPtr() {if (ref_count && --(*ref_count) == 0) {delete ptr;delete ref_count;}}SharedPtr& operator=(const SharedPtr& other) {if (this != &other) {// 先增加other的引用计数if (other.ref_count) {++(*other.ref_count);}// 减少自己的引用计数if (ref_count && --(*ref_count) == 0) {delete ptr;delete ref_count;}ptr = other.ptr;ref_count = other.ref_count;}return *this;}size_t use_count() const {return ref_count ? *ref_count : 0;}
};
11.3 多态和继承
1. 如何实现多态?
// 1. 编译时多态(静态多态)
// - 函数重载
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }// - 模板
template<typename T>
T max(T a, T b) { return a > b ? a : b; }// 2. 运行时多态(动态多态)
// - 虚函数
class Animal {
public:virtual void speak() { std::cout << "Animal speaks\n"; }virtual ~Animal() {}
};class Dog : public Animal {
public:void speak() override { std::cout << "Dog barks\n"; }
};class Cat : public Animal {
public:void speak() override { std::cout << "Cat meows\n"; }
};// 使用多态
void makeAnimalSpeak(Animal* animal) {animal->speak(); // 动态绑定
}Animal* dog = new Dog();
Animal* cat = new Cat();
makeAnimalSpeak(dog); // 输出:Dog barks
makeAnimalSpeak(cat); // 输出:Cat meows
2. 虚函数和纯虚函数的区别?
// 虚函数 - 有默认实现
class Base {
public:virtual void func() {std::cout << "Base implementation\n";}
};// 纯虚函数 - 没有实现,必须在派生类中实现
class AbstractBase {
public:virtual void pureFunc() = 0; // 纯虚函数
};// 包含纯虚函数的类是抽象类,不能实例化
// AbstractBase obj; // 错误class Concrete : public AbstractBase {
public:void pureFunc() override {std::cout << "Concrete implementation\n";}
};// 纯虚析构函数的特殊情况
class Abstract {
public:virtual ~Abstract() = 0; // 纯虚析构函数
};// 纯虚析构函数必须提供实现
Abstract::~Abstract() {} // 必须实现
3. 多重继承的问题和解决方案?
// 菱形继承问题
class A {
public:int value;A() : value(0) {}
};class B : public A {
public:B() { value = 1; }
};class C : public A {
public:C() { value = 2; }
};class D : public B, public C {
public:// D有两份A的实例,产生二义性void print() {// std::cout << value; // 错误:二义性std::cout << B::value << " " << C::value << "\n";}
};// 解决方案:虚继承
class A {
public:int value;A() : value(0) {}
};class B : virtual public A {
public:B() { value = 1; }
};class C : virtual public A {
public:C() { value = 2; }
};class D : public B, public C {
public:// D只有一份A的实例void print() {std::cout << value << "\n"; // 正确}
};// 虚继承的内存布局更复杂,有额外的开销
4. override和final的作用?
// override - 明确表示重写虚函数
class Base {
public:virtual void func(int) {}virtual void func2() {}
};class Derived : public Base {
public:// 使用override可以在编译时检查是否正确重写void func(int) override {} // 正确// void func(double) override {} // 错误:没有匹配的虚函数// 没有override,拼写错误会创建新函数void func2() {} // 重写void fucn2() {} // 新函数(拼写错误)
};// final - 防止继承或重写
class Base {
public:virtual void func() final {} // 不能被重写
};class Derived : public Base {
public:// void func() override {} // 错误:func是final的
};class FinalClass final { // 不能被继承
};// class Derived : public FinalClass {}; // 错误
11.4 STL相关
1. vector的扩容机制?
// vector扩容策略(通常是2倍或1.5倍)
std::vector<int> vec;
std::cout << "Initial capacity: " << vec.capacity() << "\n";for (int i = 0; i < 20; ++i) {vec.push_back(i);std::cout << "Size: " << vec.size() << ", Capacity: " << vec.capacity() << "\n";
}// 手动管理容量
vec.reserve(100); // 预分配空间,避免多次扩容
vec.shrink_to_fit(); // 释放多余空间// 扩容时的拷贝问题
class ExpensiveToCopy {// 大型对象
};std::vector<ExpensiveToCopy> vec;
vec.reserve(1000); // 预分配,避免扩容时的拷贝
2. map和unordered_map的区别?
// map - 基于红黑树,有序
std::map<int, std::string> orderedMap;
// - 插入/查找/删除:O(log n)
// - 有序遍历
// - 空间开销相对较小
// - 迭代器稳定// unordered_map - 基于哈希表,无序
std::unordered_map<int, std::string> hashMap;
// - 插入/查找/删除:平均O(1),最坏O(n)
// - 无序
// - 空间开销较大(哈希表)
// - 迭代器可能失效(rehash时)// 自定义类型作为key
struct Point {int x, y;bool operator<(const Point& other) const {return x < other.x || (x == other.x && y < other.y);}
};std::map<Point, int> pointMap; // 需要operator<// unordered_map需要哈希函数和相等比较
struct PointHash {size_t operator()(const Point& p) const {return std::hash<int>()(p.x) ^ (std::hash<int>()(p.y) << 1);}
};struct PointEqual {bool operator()(const Point& a, const Point& b) const {return a.x == b.x && a.y == b.y;}
};std::unordered_map<Point, int, PointHash, PointEqual> pointHashMap;
3. 迭代器失效问题?
// vector迭代器失效
std::vector<int> vec = {1, 2, 3, 4, 5};// 插入/删除可能导致迭代器失效
for (auto it = vec.begin(); it != vec.end(); ) {if (*it == 3) {it = vec.erase(it); // erase返回下一个有效迭代器} else {++it;}
}// 错误示例
for (auto it = vec.begin(); it != vec.end(); ++it) {if (*it == 3) {vec.erase(it); // 迭代器失效!}
}// map/set迭代器相对稳定
std::map<int, int> m = {{1, 1}, {2, 2}, {3, 3}};
for (auto it = m.begin(); it != m.end(); ) {if (it->first == 2) {it = m.erase(it); // C++11返回下一个迭代器} else {++it;}
}// unordered_map的rehash会导致所有迭代器失效
std::unordered_map<int, int> um;
auto it = um.begin();
um.rehash(1000); // it可能失效
11.5 现代C++特性
1. 移动语义的优势?
// 避免不必要的拷贝
std::vector<std::string> createVector() {std::vector<std::string> v;v.reserve(1000);for (int i = 0; i < 1000; ++i) {v.push_back("Long string " + std::to_string(i));}return v; // 返回值优化或移动语义
}// 移动构造函数和移动赋值
class Buffer {
private:size_t size;char* data;public:// 移动构造函数Buffer(Buffer&& other) noexcept: size(other.size), data(other.data) {other.size = 0;other.data = nullptr;}// 移动赋值运算符Buffer& operator=(Buffer&& other) noexcept {if (this != &other) {delete[] data;size = other.size;data = other.data;other.size = 0;other.data = nullptr;}return *this;}
};// 使用std::move
std::vector<Buffer> buffers;
Buffer buf(1024);
buffers.push_back(std::move(buf)); // 移动而非拷贝
2. lambda表达式的实现原理?
// lambda表达式会被编译器转换为函数对象
auto lambda = [capture](int x) { return x + capture; };// 等价于:
class LambdaClass {
private:int capture;
public:LambdaClass(int c) : capture(c) {}int operator()(int x) const {return x + capture;}
};// 捕获方式的影响
int value = 42;// 值捕获
auto lambda1 = [value]() { return value; };// 引用捕获
auto lambda2 = [&value]() { return value; };// 通用捕获(C++14)
auto lambda3 = [p = std::make_unique<int>(42)]() {return *p;
};// mutable lambda
auto counter = [count = 0]() mutable {return ++count;
};
3. constexpr和const的区别?
// const - 运行时常量
const int runtime_const = someFunction();// constexpr - 编译时常量
constexpr int compile_time_const = 42;// constexpr函数
constexpr int factorial(int n) {return n <= 1 ? 1 : n * factorial(n - 1);
}// 编译时计算
constexpr int fact5 = factorial(5); // 120// constexpr可以用于更复杂的场景
template<int N>
struct Array {int data[N];
};Array<factorial(5)> arr; // 编译时确定大小// C++14/17/20放松了constexpr的限制
constexpr int complex_computation() {int result = 0;for (int i = 0; i < 10; ++i) {result += i;}return result;
}
12. 最佳实践
12.1 代码设计原则
SOLID原则
// 1. 单一职责原则(Single Responsibility Principle)
// 错误示例
class Employee {
public:void calculatePay() {}void saveToDatabase() {} // 违反SRPvoid sendEmail() {} // 违反SRP
};// 正确示例
class Employee {
public:void calculatePay() {}
};class EmployeeRepository {
public:void save(const Employee& emp) {}
};class EmailService {
public:void sendEmail(const Employee& emp) {}
};// 2. 开闭原则(Open-Closed Principle)
// 对扩展开放,对修改关闭
class Shape {
public:virtual double area() const = 0;
};class Circle : public Shape {double radius;
public:double area() const override {return 3.14159 * radius * radius;}
};// 新增形状不需要修改现有代码
class Rectangle : public Shape {double width, height;
public:double area() const override {return width * height;}
};// 3. 里氏替换原则(Liskov Substitution Principle)
// 派生类应该可以替换基类
class Bird {
public:virtual void fly() {}
};// 错误:企鹅不能飞
class Penguin : public Bird {
public:void fly() override {throw std::runtime_error("Penguins can't fly!");}
};// 正确:重新设计继承层次
class Bird {};
class FlyingBird : public Bird {
public:virtual void fly() {}
};
class Penguin : public Bird {};// 4. 接口隔离原则(Interface Segregation Principle)
// 客户端不应该依赖它不需要的接口
// 错误示例
class Worker {
public:virtual void work() = 0;virtual void eat() = 0;virtual void sleep() = 0;
};// 正确示例
class Workable {
public:virtual void work() = 0;
};class Eatable {
public:virtual void eat() = 0;
};class Human : public Workable, public Eatable {
public:void work() override {}void eat() override {}
};// 5. 依赖倒置原则(Dependency Inversion Principle)
// 高层模块不应该依赖低层模块
class IDatabase {
public:virtual void save(const std::string& data) = 0;
};class MySQLDatabase : public IDatabase {
public:void save(const std::string& data) override {}
};class UserService {
private:std::unique_ptr<IDatabase> db;
public:UserService(std::unique_ptr<IDatabase> database): db(std::move(database)) {}
};
12.2 资源管理
// 1. 使用RAII管理资源
template<typename T>
class ScopedPtr {
private:T* ptr;
public:explicit ScopedPtr(T* p = nullptr) : ptr(p) {}~ScopedPtr() { delete ptr; }// 禁止拷贝ScopedPtr(const ScopedPtr&) = delete;ScopedPtr& operator=(const ScopedPtr&) = delete;T& operator*() const { return *ptr; }T* operator->() const { return ptr; }
};// 2. 优先使用智能指针
class ResourceManager {
private:std::unique_ptr<Resource> resource;std::shared_ptr<SharedResource> sharedRes;public:ResourceManager() : resource(std::make_unique<Resource>()),sharedRes(std::make_shared<SharedResource>()) {}
};// 3. 避免循环引用
class Node {
public:std::shared_ptr<Node> next;std::weak_ptr<Node> parent; // 使用weak_ptr避免循环引用
};// 4. 自定义删除器
auto fileDeleter = [](FILE* f) {if (f) fclose(f);
};std::unique_ptr<FILE, decltype(fileDeleter)> file(fopen("data.txt", "r"), fileDeleter);
12.3 错误处理
// 1. 使用异常而非错误码
// 错误码方式(不推荐)
int divide(int a, int b, int& result) {if (b == 0) return -1; // 错误码result = a / b;return 0;
}// 异常方式(推荐)
int divide(int a, int b) {if (b == 0) {throw std::invalid_argument("Division by zero");}return a / b;
}// 2. 异常安全性保证
// 基本保证:异常发生时,对象保持有效状态
// 强保证:异常发生时,状态不改变
// 不抛出保证:操作保证不抛出异常class Vector {
private:int* data;size_t size;size_t capacity;public:// 强异常安全的push_backvoid push_back(int value) {if (size == capacity) {// 先分配新内存size_t newCapacity = capacity * 2;int* newData = new int[newCapacity];// 拷贝数据try {std::copy(data, data + size, newData);} catch (...) {delete[] newData;throw;}// 成功后才修改状态delete[] data;data = newData;capacity = newCapacity;}data[size++] = value;}// noexcept函数size_t getSize() const noexcept {return size;}
};// 3. RAII和异常
void processFile(const std::string& filename) {std::ifstream file(filename); // RAIIif (!file) {throw std::runtime_error("Cannot open file");}// 处理文件// 即使抛出异常,文件也会被正确关闭
}
12.4 性能优化建议
// 1. 避免过早优化
// 先写正确的代码,再考虑优化// 2. 使用合适的数据结构
// O(n) 查找
std::vector<int> vec;
auto it = std::find(vec.begin(), vec.end(), target);// O(log n) 查找
std::set<int> s;
auto it = s.find(target);// O(1) 平均查找
std::unordered_set<int> us;
auto it = us.find(target);// 3. 减少不必要的拷贝
// 使用const引用传递大对象
void process(const LargeObject& obj);// 使用移动语义
std::vector<LargeObject> objects;
objects.push_back(std::move(largeObj));// 使用emplace构造
objects.emplace_back(constructor_args);// 4. 编译器优化
// 使用内联
inline int small_function(int x) {return x * 2;
}// 使用constexpr
constexpr int compile_time_calc(int x) {return x * x + 2 * x + 1;
}// 5. 缓存友好的代码
// 行优先遍历(缓存友好)
for (int i = 0; i < rows; ++i) {for (int j = 0; j < cols; ++j) {matrix[i][j] = 0;}
}// 6. 并行化
#include <execution>
std::vector<int> data(1000000);
// 并行排序
std::sort(std::execution::par_unseq, data.begin(), data.end());// 7. 内存池
template<typename T>
class ObjectPool {// ... 实现见前文
};
12.5 代码风格和规范
// 1. 命名规范
class ClassName { // 类名:大驼峰
private:int member_variable_; // 成员变量:下划线结尾static int static_var_; // 静态变量public:void memberFunction(); // 成员函数:小驼峰static void StaticFunction(); // 静态函数:大驼峰
};const int kConstantValue = 42; // 常量:k前缀
#define MACRO_NAME 100 // 宏:全大写// 2. 头文件保护
#ifndef PROJECT_MODULE_HEADER_H_
#define PROJECT_MODULE_HEADER_H_// ... 头文件内容#endif // PROJECT_MODULE_HEADER_H_// 或使用
#pragma once// 3. 前向声明
class MyClass; // 前向声明,减少编译依赖// 4. 使用namespace
namespace project {
namespace module {class Implementation {// ...
};} // namespace module
} // namespace project// 5. 注释规范
/*** @brief 计算两个数的和* @param a 第一个加数* @param b 第二个加数* @return 两数之和*/
int add(int a, int b) {return a + b;
}// 6. 包含顺序
#include <iostream> // 1. C++标准库
#include <vector>#include <sys/types.h> // 2. C标准库#include <boost/regex.hpp> // 3. 第三方库#include "myproject/public.h" // 4. 项目公共头文件#include "implementation.h" // 5. 本文件对应的头文件
12.6 测试和调试
// 1. 单元测试
#include <gtest/gtest.h>class Calculator {
public:int add(int a, int b) { return a + b; }int divide(int a, int b) {if (b == 0) throw std::invalid_argument("Division by zero");return a / b;}
};TEST(CalculatorTest, AddTest) {Calculator calc;EXPECT_EQ(calc.add(2, 3), 5);EXPECT_EQ(calc.add(-1, 1), 0);
}TEST(CalculatorTest, DivideTest) {Calculator calc;EXPECT_EQ(calc.divide(10, 2), 5);EXPECT_THROW(calc.divide(10, 0), std::invalid_argument);
}// 2. 断言
#include <cassert>void process(int* ptr) {assert(ptr != nullptr); // Debug模式下检查// 使用ptr
}// 3. 日志
class Logger {
public:enum Level { DEBUG, INFO, WARNING, ERROR };void log(Level level, const std::string& message) {// 实现日志记录}
};#define LOG_DEBUG(msg) logger.log(Logger::DEBUG, msg)
#define LOG_INFO(msg) logger.log(Logger::INFO, msg)// 4. 调试技巧
// 条件断点
for (int i = 0; i < 1000; ++i) {if (i == 500) { // 在这里设置断点int breakpoint = 0;}process(i);
}// 打印调试信息
#ifdef DEBUG#define DEBUG_PRINT(x) std::cout << #x << " = " << x << std::endl
#else#define DEBUG_PRINT(x)
#endif