基本的 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,程式可能很容易變得格式錯誤,無需診斷。