目录
[1. C++ 基础知识](#1. C++ 基础知识)
[1.1 数据类型与类型转换](#1.1 数据类型与类型转换)
[1.2 const 关键字](#1.2 const 关键字)
[1.3 引用](#1.3 引用)
[1.4 指针](#1.4 指针)
[1.5 函数](#1.5 函数)
[2. 内存管理](#2. 内存管理)
[2.1 内存布局](#2.1 内存布局)
[2.2 动态内存管理](#2.2 动态内存管理)
[2.3 智能指针](#2.3 智能指针)
[2.4 内存泄漏检测](#2.4 内存泄漏检测)
[3. 面向对象编程](#3. 面向对象编程)
[3.1 类的基本概念](#3.1 类的基本概念)
[3.2 继承](#3.2 继承)
[3.3 多态](#3.3 多态)
[3.4 RAII (Resource Acquisition Is Initialization)](#3.4 RAII (Resource Acquisition Is Initialization))
[4. 模板与泛型编程](#4. 模板与泛型编程)
[4.1 函数模板](#4.1 函数模板)
[4.2 类模板](#4.2 类模板)
[4.3 模板元编程](#4.3 模板元编程)
[4.4 概念与约束 (C++20)](#4.4 概念与约束 (C++20))
[5. STL 标准模板库](#5. STL 标准模板库)
[5.1 容器](#5.1 容器)
[5.2 迭代器](#5.2 迭代器)
[5.3 算法](#5.3 算法)
[5.4 函数对象与Lambda](#5.4 函数对象与Lambda)
[6. 现代 C++ 特性](#6. 现代 C++ 特性)
[6.1 C++11 特性](#6.1 C++11 特性)
[6.2 C++14 特性](#6.2 C++14 特性)
[6.3 C++17 特性](#6.3 C++17 特性)
[6.4 C++20 特性](#6.4 C++20 特性)
[7. 设计模式](#7. 设计模式)
[7.1 创建型模式](#7.1 创建型模式)
[7.2 结构型模式](#7.2 结构型模式)
[7.3 行为型模式](#7.3 行为型模式)
[8. 性能优化](#8. 性能优化)
[8.1 编译器优化](#8.1 编译器优化)
[8.2 内存优化](#8.2 内存优化)
[8.3 算法优化](#8.3 算法优化)
[8.4 并行优化](#8.4 并行优化)
[8.5 性能分析工具](#8.5 性能分析工具)
[9. 多线程与并发](#9. 多线程与并发)
[9.1 线程基础](#9.1 线程基础)
[9.2 互斥量与锁](#9.2 互斥量与锁)
[9.3 条件变量](#9.3 条件变量)
[9.4 原子操作](#9.4 原子操作)
[9.5 并发工具](#9.5 并发工具)
[10. 编译与链接](#10. 编译与链接)
[10.1 编译过程](#10.1 编译过程)
[10.2 链接类型](#10.2 链接类型)
[10.3 符号可见性](#10.3 符号可见性)
[10.4 模板实例化](#10.4 模板实例化)
[11. 常见面试题](#11. 常见面试题)
[11.1 语言特性相关](#11.1 语言特性相关)
[1. 指针和引用的区别?](#1. 指针和引用的区别?)
[2. const的用法?](#2. const的用法?)
[3. static的用法?](#3. static的用法?)
[4. 虚函数的实现原理?](#4. 虚函数的实现原理?)
[5. 什么是RAII?](#5. 什么是RAII?)
[11.2 内存相关](#11.2 内存相关)
[1. 内存泄漏如何检测和避免?](#1. 内存泄漏如何检测和避免?)
[2. new/malloc的区别?](#2. new/malloc的区别?)
[3. 智能指针的实现原理?](#3. 智能指针的实现原理?)
[11.3 多态和继承](#11.3 多态和继承)
[1. 如何实现多态?](#1. 如何实现多态?)
[2. 虚函数和纯虚函数的区别?](#2. 虚函数和纯虚函数的区别?)
[3. 多重继承的问题和解决方案?](#3. 多重继承的问题和解决方案?)
[4. override和final的作用?](#4. override和final的作用?)
[11.4 STL相关](#11.4 STL相关)
[1. vector的扩容机制?](#1. vector的扩容机制?)
[2. map和unordered_map的区别?](#2. map和unordered_map的区别?)
[3. 迭代器失效问题?](#3. 迭代器失效问题?)
[11.5 现代C++特性](#11.5 现代C++特性)
[1. 移动语义的优势?](#1. 移动语义的优势?)
[2. lambda表达式的实现原理?](#2. lambda表达式的实现原理?)
[3. constexpr和const的区别?](#3. constexpr和const的区别?)
[12. 最佳实践](#12. 最佳实践)
[12.1 代码设计原则](#12.1 代码设计原则)
[12.2 资源管理](#12.2 资源管理)
[12.3 错误处理](#12.3 错误处理)
[12.4 性能优化建议](#12.4 性能优化建议)
[12.5 代码风格和规范](#12.5 代码风格和规范)
[12.6 测试和调试](#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, 3
std::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 byte
int b; // 4 bytes (3 bytes padding)
char c; // 1 byte (3 bytes padding)
// Total: 12 bytes
};
// 正确示例
struct Good {
int b; // 4 bytes
char a; // 1 byte
char 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 for
for (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(); // 8
t.join();
}
// shared_future
void use_shared_future() {
std::promise<int> promise;
std::shared_future<int> future = promise.get_future().share();
// 多个线程可以访问同一个shared_future
std::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")))
#endif
class 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() {} // 违反SRP
void 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_back
void 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); // RAII
if (!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