Абстрактный класс - сокрытие реализации в практике C ++ - PullRequest
6 голосов
/ 26 января 2010

Недавно я писал код, подобный этому:

messagehandler.h:

#include "message.h"
class MessageHandler {
public:
   virtual ~MessageHandler() {}
   virtual void HandleMessage(Message *msg) = 0:
};

persistmessagehandler.h:

MessageHandler *CreatePersistMessageHandler();

persistmessagehandler.cpp:

#include "messagehandler.h"
#include "persist.h"

class PersistMessageHandler : public MessageHandler {
private:
   PersistHandle ph;
   size_t count;
   InternalCheck();
public:
   PersistMessageHandler(int someParam);
   virtual ~PersistMessageHandler ();
   virtual void HandleMessage(Message *msg):
};
PersistMessageHandler::PersistMessageHandler(int someParam)
{
  ph.Initialize();
}
... rest of implementation.

MessageHandler *CreatePersistMessageHandler(int someParam)
{
  return new PersistMessageHandler(someParam);
}

Причина в том, чтобы скрыть PersistMessageHandler. Клиентам не нужно включать заголовок для класса PersistMessageHandler со всеми включениями и типами, которые могут потребоваться для реализации, а также для более четкого разделения интерфейса и реализации. , В любом случае, он всегда будет динамически распределен,

Все пользователи PersistMessageHandler просто вызовут CreatePersistMessageHandler (..); прямо или косвенно получить один с завода.

Но. Я не видел, чтобы этот подход использовался в других местах. Это хорошая практика? Есть ли другие / лучшие альтернативы для простых случаев?

Ответы [ 5 ]

6 голосов
/ 26 января 2010

Вы всегда должны скрывать как можно больше. Ваш способ (помещение классов реализации в .cpp) является распространенным способом сделать это в c ++.

2 голосов
/ 26 января 2010

Это хороший способ скрыть детали реализации от ваших клиентов. Если вы работаете в Windows, вы можете также рассмотреть возможность использования __interface вместо абстрактного базового класса.

Интерфейс - это расширение компилятора MSVC, которое выглядит как абстрактный базовый класс, но имеет другие правила для создания и уничтожения, чем обычный класс c ++. Это стандартный способ работы в Windows, поэтому существуют поддерживаемые системой средства для работы с внешними объектами и для использования их в коде .NET.

1 голос
/ 26 января 2010

Процесс скрытия деталей реализации называется Encapsulation . Процесс минимизации зависимостей сборки для ваших пользователей называется Insulation . Есть большая (но стареющая) книга Джона Лакоса, посвященная обеим темам:

http://www.amazon.com/Large-Scale-Software-Design-John-Lakos/dp/0201633620

1 голос
/ 26 января 2010

Конечно - это выглядит как форма фабричного образца . Пользователи фабрики не интересуются ее внутренними деталями, они заботятся только о том, что она создает.

0 голосов
/ 26 января 2010

Минимизация зависимости от деталей реализации действительно велика, и сокрытие вещей за пределами абстрактного базового класса (ABC, aka interface) является хорошим и идиоматическим решением.

Недостатком использования ABC является то, что вы теряете семантику значений вашего класса, которая может быть или не быть приемлемой / желательной.

Один метод, который также скрывает детали реализации без этого недостатка - Pimpl . Думаю, ты должен знать.

Я предпочитаю ABC в большинстве случаев.

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