October 27, 2018 by Reion

C++ PIMPL 设计模式

PIMPL 被称为 pointer to implementation 或 private implementation,在很多 C++ 项目/开发库中都是很常见的,比如 deepin 的 dtkwidget 项目,简单理解就是在公共接口里封装私有数据和方法,它将类的实现细节放在分离的指针访问类中。该方法用于构造稳定的 ABI 的 C++ 库接口,及减少编译时依赖。

实现

在现代 C++ 不鼓励使用 owning raw pointers,我们可以使用智能指针实现 PIMPL。

#include <iostream>
#include <memory>

class AppPrivate
{
public:
    AppPrivate() {}

    void print(std::string info) {
        std::cout << info << std::endl;
    }
};

class Application
{
public:
    Application(): d_ptr(new AppPrivate) {

    }

    void call_print(std::string info) {
        d_ptr->print(info);
    }

private:
    std::unique_ptr<AppPrivate> d_ptr;
};

int main(int argc, char *argv[])
{
    Application a;
    a.call_print("hello world");

    return 0;
}

最后

我们知道 C++ 头文件(.h)和源文件(.cpp),一旦头文件发生变化,不管多小的改变,所有引用它的文件都必须重新编译,对于一个很大的项目编译就会耗费大量的时间,利用 PIMPL 封装到一个类中,就可以减少编译依赖,起到了减少编译时间的效果。

d-pointer 模式是不透明指针实现之一,d-pointer 是类的私有数据成员,一方面好处是编译速度更快,因为头文件更改频率较低,d-pointer 在 Qt、KDE 库中大量使用。