根据创建的实例对象而决定,如果实例对象是const则自动调第二个,如果非const调用第一个。
析构函数不可以重载。 析构函数不重载,可能导致父类资源无法释放。 构造函数的调用顺序是,先构造父类,再构造子类。析构函数的顺序是反过来的,先析构子类,再析构父类。
#include <iostream>
class Base {
public:
Base() {
std::cout << "Base constructor called." << std::endl;
}
// 注意:这里没有将析构函数声明为虚函数
~Base() {
std::cout << "Base destructor called." << std::endl;
}
};
class Derived : public Base {
public:
Derived() {
std::cout << "Derived constructor called." << std::endl;
}
~Derived() {
std::cout << "Derived destructor called." << std::endl;
}
};
int main() {
Base* ptr = new Derived(); // 创建一个Derived对象,并用Base指针指向它
delete ptr; // 通过基类指针删除对象
return 0;
}
// 如果析构不是虚函数,那么只会释放父类的资源,而泄露了子类的资源如果想要将父类转换为子类,需要父类中至少有一个虚函数,dynmic_cast依赖于运行时类型信息(RTTI),因此需要虚函数的存在。
## #include <iostream>
#include <exception>
class Base {
public:
virtual ~Base() {} // 基类需要至少一个虚函数(通常是析构函数),以支持RTTI
};
class Derived1 : public Base {
public:
void derived1Function() {
std::cout << "Derived1 function called." << std::endl;
}
};
class Derived2 : public Base {
public:
void derived2Function() {
std::cout << "Derived2 function called." << std::endl;
}
};
int main() {
Base* basePtr1 = new Derived1();
Base* basePtr2 = new Derived2();
// 尝试将 basePtr1 转换为 Derived1*
Derived1* derivedPtr1 = dynamic_cast<Derived1*>(basePtr1);
if (derivedPtr1) {
derivedPtr1->derived1Function();
} else {
std::cout << "Conversion to Derived1 failed." << std::endl;
}
// 尝试将 basePtr2 转换为 Derived1*(应该失败)
Derived1* derivedPtr2 = dynamic_cast<Derived1*>(basePtr2);
if (derivedPtr2) {
derivedPtr2->derived1Function();
} else {
std::cout << "Conversion to Derived1 failed (as expected)." << std::endl;
}
// 清理内存
delete basePtr1;
delete basePtr2;
return 0;
}柔性数组(Flexible Array Member)是C99引入的特性,允许结构体的最后一个成员是未知大小的数组。
typedef struct {
int length;
char data[]; // 柔性数组,不占用结构体大小
} Buffer;用处:
- 减少内存分配次数(只需一次malloc)
- 内存连续,提高缓存命中率
- 灵活处理变长数据
- 大端(Big-Endian):高位字节存储在低地址
- 小端(Little-Endian):低位字节存储在低地址
判断代码:
bool isLittleEndian() {
int num = 1;
return *(char*)&num == 1;
}- Valgrind:
valgrind --leak-check=full ./program - AddressSanitizer: 编译时加
-fsanitize=address - mtrace: 使用
mtrace()和muntrace() - 智能指针: 使用
std::shared_ptr/std::unique_ptr - 自定义内存分配器: 重载
new/delete追踪分配
# 记录性能数据
perf record -g ./program
# 查看报告
perf report
# 查看热点函数
perf top
# 统计缓存未命中
perf stat -e cache-misses ./program- 栈区:局部变量、函数参数,自动管理
- 堆区:动态分配(malloc/new),手动管理
- 全局/静态区:全局变量、静态变量
- 代码区:程序指令
- 常量区:字符串常量、const变量
C++11内存模型还定义了:
- 原子操作的内存序(memory_order_relaxed/acquire/release/seq_cst)
- happens-before关系
内存对齐:数据存储在地址为数据大小整数倍的内存位置。
原因:
- 硬件要求:某些架构只能访问对齐地址
- 性能优化:未对齐访问需要多次内存读取
- 原子操作保证:对齐地址上的操作是原子的
- 减少内存分配:使用内存池、对象池
- 缓存友好:数据局部性,避免伪共享
- SIMD指令:使用AVX/SSE向量化
- 预取:
__builtin_prefetch预加载数据 - 内联函数:减少函数调用开销
- 编译器优化:
-O3, LTO链接时优化 - 无锁编程:CAS操作代替锁
- 分支预测: likely/unlikely 提示
#ifdef __cplusplus
extern "C" {
#endif
// C兼容的声明
void c_function(void);
#ifdef __cplusplus
}
#endifextern "C"禁用C++名称修饰,确保C能链接
静态成员函数只能访问静态成员变量。静态成员变量在所有对象中共享。
class Singleton {
public:
static Singleton& getInstance() {
static Singleton instance; // C++11保证线程安全
return instance;
}
// 禁止拷贝和赋值
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
Singleton() = default;
};判断链表有环:快慢指针(Floyd判圈算法)
bool hasCycle(ListNode* head) {
ListNode *slow = head, *fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) return true;
}
return false;
}链表排序:归并排序(O(n log n),稳定)
二叉树层序遍历:BFS使用队列
判断正方形:
- 四条边相等,两条对角线相等
- 或对角线相等且互相垂直平分
- 大页内存:使用HugePage(2MB/1GB)减少页表项
- 数据局部性:连续访问内存,减少页切换
- 减少工作集:只保留必要数据在内存
- 预映射:
mlock锁定关键页面 - NUMA优化:线程绑定本地内存
- 多态场景:通过基类指针调用派生类实现
- 接口设计:抽象基类定义接口
- 运行时类型判断:配合
dynamic_cast使用 - 析构函数:有继承关系的类必须虚析构
想要malloc和new时,不用显式分配内存和管理内存,就可以使用智能指针。
移动语义:转移资源所有权,避免深拷贝
std::vector<int> v1 = {1,2,3};
std::vector<int> v2 = std::move(v1); // 移动构造完美转发:保持值的类别(左值/右值)传递参数
template<typename T>
void wrapper(T&& arg) {
func(std::forward<T>(arg)); // 完美转发
}- 使用
std::forward和万能引用T&&
协程是挂起/恢复执行的函数,包含三个关键字:
co_await:挂起等待结果co_yield:生成值并挂起co_return:返回并结束
std::generator<int> range(int n) {
for (int i = 0; i < n; ++i)
co_yield i;
}应用场景:异步I/O、生成器、状态机
- 预处理(Preprocessing):宏展开、头文件包含、条件编译
- 编译(Compilation):生成汇编代码
- 汇编(Assembly):生成目标文件(.o/.obj)
- 链接(Linking):合并目标文件和库,解析符号引用
内存分配器:
- ptmalloc(glibc默认)
- jemalloc(多线程友好)
- tcmalloc(Google)
避免碎片:
- 内存池:预分配固定大小块
- 对象池:复用对象
- 伙伴系统:分配2^n大小块
- ** slab分配器**:按大小分类缓存
- 保存当前线程的寄存器状态(PC、SP、通用寄存器)
- 保存线程的虚拟内存映射(页表指针)
- 选择下一个执行的线程(调度器)
- 恢复新线程的寄存器状态
- 刷新TLB(如果是进程切换)
- 跳转到新线程的程序计数器继续执行
开销:几十微秒到几百微秒,涉及内核态切换
- CPU发出虚拟地址
- MMU查询TLB缓存:命中则直接得到物理地址
- TLB未命中:查询页表(多级页表遍历)
- 页表项有效:更新TLB,转换为物理地址
- 页表项无效:触发缺页中断,从磁盘加载页面
- 物理地址发送到内存总线访问数据
减小粒度:
- 分段锁:将大锁拆分为多个小锁
- 读写锁:
std::shared_mutex区分读写 - 无锁数据结构:CAS操作
- Thread-Local:每个线程独立数据
避免死锁:
- 锁顺序一致:所有线程按相同顺序获取锁
- 超时机制:
std::try_lock_for - 死锁检测:资源分配图检测循环
- 避免持有锁时调用外部代码
- 不可变数据:const数据天然线程安全
- 原子操作:
std::atomic对基本类型 - 互斥锁:
std::mutex保护临界区 - 条件变量:
std::condition_variable同步 - 线程局部存储:
thread_local变量 - 无锁设计:消息队列、RCU机制
使用优先队列 + 条件变量:
class DelayedQueue {
std::priority_queue<Task> pq;
std::mutex mtx;
std::condition_variable cv;
public:
void push(Task task) {
std::lock_guard<std::mutex> lock(mtx);
pq.push(task);
cv.notify_one();
}
Task pop() {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [this]{ return !pq.empty() && pq.top().ready(); });
Task t = pq.top(); pq.pop();
return t;
}
};CAS(Compare-And-Swap):比较内存值与预期值,相等则更新
std::atomic<int> value;
int expected = old_val;
bool success = value.compare_exchange_strong(expected, new_val);ABA问题解决:
- 使用带版本号的指针(Tagged Pointer)
std::atomic的 compare_exchange 自动处理
自旋锁实现:
class SpinLock {
std::atomic<bool> flag{false};
public:
void lock() {
while (flag.exchange(true, std::memory_order_acquire));
}
void unlock() {
flag.store(false, std::memory_order_release);
}
};(请根据个人实际情况填写)
This repository also contains technical requirements for various C++ career directions:
- autonomous_driving - Autonomous Driving / 自动驾驶
- audio_video - Audio-Video Processing / 音视频
- game_development - Game Development / 游戏开发
- server_development - Server Development / 服务器开发
- live_streaming - Live Streaming / 直播推流
- search_ads_rec - Search, Ads, Recommendation / 搜广推
- compiler - Compiler Development / 编译器开发
- database_system - Database System / 数据库系统
- storage_system - Storage System / 存储系统