6

Recently I've been writing code similar to this:

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);
}

The reasoning here is to hide the PersistMessageHandler. Clients don't need to include a header for the PersistMessageHandler class, with all the includes and types the implementation might need, and to more cleanly seperate the interface and implementation. . It'll always be dynamically allocated anyway,

All PersistMessageHandler users will just call CreatePersistMessageHandler(..); directly or indirectly get one from a factory.

But. I've not seen this approach used much elsewhere. Is the above good practice ? Are there other/better alternatives for simple cases ?

Anonym
  • 3,052
  • 4
  • 28
  • 32
  • Why would anyone ever abbreviate "Message" to "Messge"? Is it a typo? – unwind Jan 26 '10 at 09:24
  • Great question! I do this all the time and have always wondered if it was kosher. Except my declaration is: `std::auto_ptr CreatePersistMessageHandler();` – Travis Gockel Jan 26 '10 at 09:25
  • See also http://stackoverflow.com/questions/825018/pimpl-idiom-vs-pure-virtual-class-interface – Frank Feb 03 '10 at 15:17

5 Answers5

6

You always have to hide as much as possible. Your way (putting implementation classes into .cpp) is a common way to do this in c++.

Mykola Golubyev
  • 52,197
  • 14
  • 81
  • 101
2

This is a good way to hide implementation details from your clients. If you are working in Windows, you might also consider using an __interface instead of an abstract base class.

An Interface is an MSVC compiler extension that looks like an abstract base class, but has different rules for creation and destruction than a normal c++ class. It's the standard way of working in Windows, so there are system supported facilities for working with out-of-process objects and for using them in .NET code.

John Knoeller
  • 31,289
  • 4
  • 56
  • 90
1

Sure - it looks like a form of the factory pattern. Users of the factory aren't interested in its internal details, they only care about the things it creates.

1

The process of hiding the implementation details is called Encapsulation. The process of minimizing build dependencies for your users is called Insulation. There is a great (but aging) book by John Lakos devoted to both topics:

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

BenG
  • 1,272
  • 8
  • 11
0

Minimizing dependency on implementation details is indeed great, and hiding things beyond abstract base class (ABC, aka interface) is a good and idiomatic solution.

The downside of using ABC is that you lose value semantics of your class which could be or couldn't be acceptable/desirable.

One technique that also hide implementation details without this drawback is Pimpl. Guess you should be aware.

I'll prefer ABC in most cases.

Alexander Poluektov
  • 7,212
  • 25
  • 30