Я реализую несколько классов, используя идиому pimpl, и сталкиваюсь с некоторыми проблемами дизайна.
Во-первых, я всегда видел, как pimpl делают вот так
class Object
{
public:
Visible();
~Visible();
.. etc ..
private:
class ObjectImpl *_pimpl;
};
У меня есть несколько классов, которые используют этот подход, и моя проблема в том, что некоторым из этих классов требуется доступ к деталям реализации друг друга, но указатель _pimpl является закрытым.
Может ли кто-нибудь увидеть обратную сторону объявления _pimpl общедоступным. Очевидно, что если он публичный, то кто-то может случайно (или намеренно) переназначить его. (Я игнорирую тот факт, что "частный" может быть # определен как "общедоступный" и в любом случае предоставить доступ. Если вы сделаете это, то вы заслуживаете того, что получаете).
Я понимаю, что мой дизайн может быть небезупречным, и приветствую любые комментарии по этому поводу.
Мне очень не нравится использовать друзей, и я не уверен, что они даже помогут, поскольку вы не можете пересылать объявление Object :: ObjectImpl без полного определения Object.
i.e.
...
private:
class ObjectImpl *_pimpl;
friend class OtherObject::OtherObjectImpl; // this needs a fully qualified OtherObject
};
Спасибо, Марк.
* ОБНОВЛЕНИЕ - Подробнее **
У меня есть два класса: один называется Command, а другой - Results. У меня есть методы Command, которые возвращают вектор результатов.
И команда, и результаты используют идиому pimpl. Я хочу, чтобы интерфейс с результатами был как можно меньше.
class Command
{
public:
void getResults( std::vector< Results > & results );
void prepareResults( std::vector< Results > & results );
private:
class CommandImpl *_pimpl;
};
class Results
{
public:
class ResultsImpl;
Results( ResultsImpl * pimpl ) :
_pimpl( impl )
{
}
private
ResultsImpl *_pimpl;
};
Теперь в Command :: getResults (). Я добавляю ResultsImpl в результаты. в Command :: prepareResults () мне нужен доступ к ResultsImpl.
M.