c ++: общий код в реализациях pimpl - PullRequest
2 голосов
/ 03 ноября 2011

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

Другим вариантом могут быть абстрактные интерфейсы, я думаю.используя pimpl для всего моего проекта, я действительно не думаю, что было бы неплохо смешивать его с абстрактными интерфейсами (на уровне API).

Итак, какие варианты вы бы предложили для совместного использования кода между различными pimpls?Я подумал об абстрактном классе интерфейса для самого pimpl, так что фактический API все еще четко отделен, но это тоже кажется странной идеей.

PS: я не хочу обсуждать, лучше ли pimpl или абстрактные интерфейсы.С точки зрения API, я решил пойти с pimpl, и я хотел бы придерживаться его.

Ответы [ 4 ]

2 голосов
/ 03 ноября 2011

Вы можете просто переместить общий код в новый независимый класс, пространство имен или модуль.

1 голос
/ 03 ноября 2011

Ваша модель классов может включать абстрактные классы, даже если реализация включает в себя pimpls. Два ортогональны.

Однако, если вы помещаете все свои приватные методы в свою pimpl, вы можете прыгнуть через несколько обручей. Вызов метода экземпляра, где бы он ни был определен, требует указателя на экземпляр. Вы можете предоставить указатель экземпляра в качестве аргумента для метода pimpl или неявно в закрытом методе во внешнем классе.

Другим вариантом будет разделение по составу, а не наследованию, что имеет свои преимущества.

1 голос
/ 03 ноября 2011

VTK имеет великолепный дизайн PIMPL. Проверьте это!

Вот стандарт кодирования VTK.

0 голосов
/ 03 ноября 2011

Если сведения о том, как вы реализуете PIMPL, можно использовать повторно, вам не следует расстраиваться из-за их обнародования. Главное - поддерживать интерфейс в чистоте.

Иногда вы хотите поделиться помощниками, которые действительно не должны использоваться извне. В этот момент , четко документирующее , что вещи не должны использоваться повторно, является реальной проблемой, которую вы пытаетесь решить . Мне нравится использовать для этого подробные / приватные заголовки.

// Implementation details, not for reuse
namespace some_public_ns {
namespace detail {
  // .. shared code
}}

Обычно вы помещаете этот подробный код в собственный заголовок. Организации обычно выбирают соглашение об именовании, чтобы избежать путаницы.

thingajig.h
thingajig_priv.h
thingajig_detail.h

Это не удержит людей с дробовиками в вашей гостиной. Я бы сказал, что вы не должны пытаться. Тем не менее, действительно трудно случайно вставить этот общий код.

Затем в ваших файлах cpp, которые повторно используют код, вы можете просто включить подробное пространство имен в пространство имен anon.

namespace some_public_ns {
namespace {
  using namespace detail;
}}

Это позволяет избежать беспорядка в ваших пространствах имен, но при этом не требуется указывать ::detail при реализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...