C++
Идиома Pimpl
Поиск…
замечания
Pimpl идиома (р ointer к осущ ementation, иногда называют непрозрачным указателем или чеширский кот техники), сокращает время компиляции класса, переместив все свои личные элементы данных в структуры , определенной в файле .cpp.
Класс владеет указателем на реализацию. Таким образом, он может быть объявлен вперед, так что заголовочный файл не должен включать #include
классы, которые используются в частных переменных-членах.
При использовании идиомы pimpl изменение частного элемента данных не требует перекомпиляции классов, которые зависят от него.
Основная идиома Pimpl
В файле заголовка:
// 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
~Widget()
должен быть реализован в точке в файле, где Impl
полностью виден. Вы можете =default
там, но if =default
где Impl
не определено, программа может легко стать плохо сформированной, не требуется диагностика.