基本的 Pimpl 成语

Version >= C++ 11

在头文件中:

// widget.h

#include <memory>  // std::unique_ptr
#include <experimental/propagate_const>

class Widget
{
    public:
        Widget();
        ~Widget();
        void DoSomething();

    private:
        // the pImpl idiom is named after the typical variable name used
        // ie, pImpl:
        struct Impl;                    // forward declaration
        std::experimental::propagate_const<std::unique_ptr< Impl >> pImpl;  // ptr to actual implementation
};

在实现文件中:

// widget.cpp

#include "widget.h"
#include "reallycomplextype.h" // no need to include this header inside widget.h

struct Widget::Impl
{
    // the attributes needed from Widget go here
    ReallyComplexType rct;
};

Widget::Widget() :
    pImpl(std::make_unique<Impl>())
{}

Widget::~Widget() = default;

void Widget::DoSomething()
{
    // do the stuff here with pImpl
}

pImpl 包含 Widget 状态(或其中的一些/大部分)。而不是在头文件中公开的状态的 Widget 描述,它只能在实现中公开。

pImpl 代表指向实现的指针Widget真实实现在 pImpl 中。

危险:请注意,为了使用 unique_ptr,必须在 Impl 完全可见的文件中的某一点实现~Widget()。你可以在那里使用它,但如果 =default 未定义 Impl,程序可能很容易变得格式错误,无需诊断。