使用 Pimpl 的目的
pImpl 不只是解决编译速度问题,主要是解决隐藏实现细节,保持二进制兼容的问题。
Pimpl
正常我们去实现一个类,先编写头文件,再去编写实现文件,类中方法实现写在 cpp 文件中,但是类的属性都写在了 h 文件中。
头文件暴露了私有成员。
实现和接口耦合在了一起,私有成员的实现和方法的实现分开了。
如果有另外一个库使用了这个库,而你的这个库实现变了,头文件就会变,而头文件一旦变动,就需要所有使用了这个库的程序都要重新编译!这个代价是巨大的。所以,我们应该尽可能地保证头文件不变动,或者说,尽可能隐藏实现,隐藏私有变量。
// foo.h - header file
#include <memory>
class foo
{
public:
foo();
~foo();
foo(foo&&);
foo& operator=(foo&&);
private:
class impl;
std::unique_ptr<impl> pimpl;
};
// foo.cpp - implementation file
class foo::impl
{
public:
void do_internal_work()
{
internal_data = 5;
}
private:
int internal_data = 0;
};
foo::foo(): pimpl{std::make_unique<impl>()} {
pimpl->do_internal_work();
}
foo::~foo() = default;
foo::foo(foo&&) = default;
foo& foo::operator=(foo&&) = default;