0%

Pimpl模式

核心思想

Pimpl 模式的主要目标是分离接口与实现,通过将类的实现细节封装在私有的实现类中,减少编译依赖并提高二进制兼容性。


示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// my_class.h
class my_class {
// 公共接口与保护成员
private:
class impl; // 不完整类型声明
std::unique_ptr<impl> pimpl; // 指向私有实现类
};

// my_class.cpp
class my_class::impl {
// 私有数据和方法
// 可以随意修改而无需重新编译客户端
};

my_class::my_class() : pimpl(new impl) {
// 初始化 impl 的值
}

优点

  1. 减少编译依赖

    • 客户端只依赖类的接口(头文件),实现细节变化无需重新编译。
  2. 分离接口和实现

    • 将类的私有数据和方法封装在 impl 中,接口保持不变。
  3. 提高可移植性和二进制兼容性

    • 修改实现类不会破坏已经编译好的客户端代码。
  4. 隐藏实现细节

    • 客户端无法直接访问实现类,保证封装性。

Pimpl vs 虚函数接口

特性 虚函数接口 Pimpl
二进制兼容性 修改虚函数表会破坏兼容性 修改 impl 不影响接口和客户端
封装性 公开继承,接口暴露实现 完全隐藏实现细节
编译依赖 接口和实现耦合,修改需要重新编译 客户端仅依赖头文件,不依赖实现

总结

  • Pimpl 模式是一种经典的 信息隐藏与接口分离 技术
  • 适合库开发或需要保持二进制兼容性的场景
  • 结合智能指针(如 unique_ptr)可安全管理资源