能进封禁网站的手机浏览器朝阳网站建设公司
C++ PIMPL 编程技巧
文章目录
- C++ PIMPL 编程技巧
- 什么是pimpl?
- pimpl优点
- 举例实现
什么是pimpl?
Pimpl (Pointer to Implementation) 是一种常见的 C++ 设计模式,用于隐藏类的实现细节,从而减少编译依赖和提高编译速度。它的基本思想是将一个外部可见类 (visible class) 的实现细节(一般是所有私有的非虚成员)放在一个单独的实现类 (implementation class) 中,而在可见类中通过一个私有指针来间接访问该实现类。这种技术用于构建具有稳定 ABI 的 C++ 库接口并减少编译时间依赖。
pimpl优点
- 接口和实现分离
- 减少头文件依赖
- 提高编译速度
举例实现
比如说我有一个Producer的对外接口:
文件如下:
producer.h //对外
producer.cc
producer_impl.h // 具体实现
producer_impl.cc // 具体实现
头文件producer.h对外。
producer.h
#include <memory>
#include <string>class ProducerImpl; // 前置声明class Producer {public:Producer();~Producer() = default;bool CreateProducer(const std::string& name);private:std::shared_ptr<ProducerImpl> impl_;
};
producer.cc
#include "producer.h"Producer::Producer() {impl_ = std::make_shared<ProducerImpl>();
}bool Producer::CreateProducer(const std::string& name) {return impl_ ->CreateProducer(name);
}
producer_impl.h
#include <string>class ProducerImpl {public:ProducerImpl ();~ProducerImpl ();bool CreateProducer(const std::string& name);
};
producer_impl.cc
#include "producer_impl.h"bool ProducerImpl::CreateProducer(const std::string& name) {// impl接口具体实现return true;
}
通过如上示例,外部用户只需包含 producer.h即可,内部实现均在impl中实现,后续如果修改也只是修改impl中的内容,并不会动对外接口。
当然最好是配合 attribute((visibility(“default”))) 来使用。attribute((visibility(“default”))) 是 GCC 编译器的一个属性,用于控制符号的可见性。它可以用来指定一个符号在动态链接时是否可见。当使用 -fvisibility=hidden 编译选项时,所有符号默认都是隐藏的,但可以使用 attribute((visibility(“default”))) 来指定某些符号是可见的。这样,可以减少动态链接库中不必要的符号,提高加载速度和运行速度。
比如上面几个文件 可以按照如下文件夹来排布:
include/producer.h
src/producer.cc
src/producer_impl.h
src/producer_impl.cc
并配合__attribute__((visibility(“default”))) 使用只将producer.h对外可见。