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