Перейти к содержанию

Последнее обновление:2026-10-12

Идиома Pimpl в C++

«Указатель на реализацию», или «pImpl», — это приём программирования на C++, который выносит детали реализации класса из представления объекта в отдельный класс, доступ к которому осуществляется через непрозрачный указатель.

Причины использовать идиому pImpl таковы:

Рассмотрим следующий пример:

class X
{
private:
  C c;
  D d;  
} ;

С применением pImpl это будет выглядеть так:

class X
{
private:
  struct XImpl;
  XImpl* pImpl;       
};

Определение на C++:

struct X::XImpl
{
  C c;
  D d;
};
  • Двоичная совместимость

При разработке библиотеки можно добавлять и изменять поля XImpl, не нарушая двоичной совместимости с клиентами (иначе это привело бы к падению!). Поскольку при добавлении новых полей в класс XImpl двоичная раскладка класса X не меняется, в минорных обновлениях библиотеки можно безопасно добавлять новую функциональность.

Разумеется, вы также можете добавлять новые открытые/закрытые невиртуальные методы в X/XImpl, не нарушая двоичной совместимости, но это сопоставимо со стандартной техникой заголовок/реализация.

  • Сокрытие данных

Если вы разрабатываете библиотеку, особенно проприетарную, вы можете не хотеть раскрывать сторонние библиотеки и технологии реализации, на которых построен публичный интерфейс вашей библиотеки. Либо из-за вопросов интеллектуальной собственности, либо потому, что вы считаете, что пользователи могут быть склонны делать опасные предположения о реализации или просто разрушать инкапсуляцию с помощью ужасающих трюков с приведением типов. PIMPL решает или смягчает эту проблему.

  • Время компиляции

Время компиляции сокращается, поскольку при добавлении/удалении полей и/или методов в класс XImpl (что в стандартной технике соответствует добавлению закрытых полей/методов) пересобрать нужно только исходный (содержащий реализацию) файл X. На практике это весьма частая операция.

При стандартной технике заголовок/реализация (без PIMPL), когда вы добавляете в X новое поле, каждый клиент, который когда-либо размещал X (на стеке или в куче), должен быть перекомпилирован, поскольку ему необходимо скорректировать размер выделения. Что ж, и каждый клиент, который никогда не размещал X, тоже должен быть перекомпилирован, но это уже чистые издержки (итоговый код на стороне клиента не меняется).

https://stackoverflow.com/questions/8972588/is-the-pimpl-idiom-really-used-in-practices

Похожие темы

Комментарии