Pimpl 编译防火墙
更新时间:2026-10-01。大型 C++ 工程降低重编译、稳定二进制接口的标准手段,也是类型擦除的近亲。
一、结构
cpp
// .h
class Widget { struct Impl; std::unique_ptr<Impl> p;
public: Widget(); ~Widget(); void f(); };
// .cpp: 定义 Widget::Impl 与全部实现头文件不再暴露成员/依赖,改 Impl 只重编该 .cpp。
二、最常见坑
unique_ptr<Impl> 的默认析构要求 Impl 完整,所以 ~Widget() 必须在 .cpp 定义;同理移动函数。需要拷贝就自己在 .cpp 实现深拷贝。

常见坑
- 头里
= default析构导致不完整类型编译错误。 - 忘了实现拷贝造成默认浅拷贝问题。
- 每层多一次堆分配与间接访问(性能敏感处权衡)。
小结
总结
Pimpl 在头文件里只留一个指向不完整类型 Impl 的智能指针、把全部成员与依赖移到 .cpp,从而构成"编译防火墙"——改实现只重编该 .cpp、不触发调用方重编译,并稳定 ABI、隐藏依赖;最关键的坑是 unique_ptr<Impl> 的默认析构/移动要求 Impl 类型完整,所以析构函数和移动函数必须在 .cpp 中定义(头里 = default 会报不完整类型错误),需要值语义时在 .cpp 自己实现深拷贝;代价是每层多一次堆分配和间接访问,性能敏感处需权衡。