C++ PIMPL模式详解 | 编译防火墙与实现隐藏

C++ PIMPL模式:优雅的实现隐藏技术 #

本文介绍一个C++中非常常用的模式:pimpl

至于它有什么作用,直接看代码:

// MyClass.h
class MyClass {
public:
    void func1();
    void func2();
private:
    class impl;
    impl* pimpl;
};

// MyClass.cc
class MyClass::impl {
public:
    void func1();
    void func2();
private:
    void func3();
    void func4();
    int a;
    int b;
};

MyClass::MyClass() {
    pimpl = new impl;
}

void MyClass::func1() {
    pimpl->func1();
}

将类的private属性隐藏进一个内部类,然后通过一个指针访问(提前声明)它的接口。

在头文件中只暴露出应该暴露的功能,然后持有一个Impl的指针,而Impl则具体在MyClass.cc中定义,用户什么都看不到。

然后所有的功能都通过Impl完成。头文件里的Impl的指针也可以通过智能指针(unique_ptr)来代替,但这不是本文的重点。

再总结一下pimpl模式的优点:

  • 非常适合隐藏private实现:如果想要在头文件中暴露public接口,但又不想暴露private实现的细节,则可以使用pimpl模式来隐藏细节。
  • pimpl模式也被称为编译防火墙,是一种用来减少编译时间的方法。通常来讲,如果头文件里的某些内容变更了,意味着所有引用该头文件的代码都要被重新编译,即使变更的是无法被用户类访问的私有成员。将这部分代码从被引用多次的头文件里移除到只被引用编译一次的源文件中,更改此文件就不会付出太长的编译时间。

参考资料 #