基本的 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
,程序可能很容易变得格式错误,无需诊断。