views:

39

answers:

1

Our code-base has a lot of COM objects, so typically we'll have something like:

//this is the IDL-generated IGetTime interface header
#include "gettime.h"

//our COM class implementation of IGetTime
class CGetTime : public IGetTime
{
  public:
    CGetTime(CGetTimeCF &factory,...); //COM-specific constructor params
    /* IUnknown */
    STDMETHODIMP QueryInterface(REFIID riid, LPVOID FAR * ppv);
    STDMETHODIMP_(ULONG) AddRef();
    STDMETHODIMP_(ULONG) Release();

    /* IGetTime */
    STDMETHODIMP GetTheTime(); //
};

The way the constructor and a few other things are set up, this class is only easily usable through COM... you can hack a way to create the object but it tends to be flaky. I many cases though, the actual functionality of the class might be usable without COM... and this would also be more easily testable if you could do new CGetTime();

I wondered about having something like this as a pattern:

class CGetTimeBase
{
 public:
  STDMETHODIMP GetTheTime();
};

class CGetTime : public IGetTime, public CGetTimeBase
{
...
};

Is this a good approach, or is there a better way to have a 'plain C++' class providing the core functionality, and a COM class doing the COM stuff? To minimise amount of code to write I'd rather not introduce wrapper methods, I think, but have the actual implementation method in the non-COM class so it's automatically present in the COM class.

Thoughts? };

+5  A: 

Where I work, we chose to separate core C++ classes from the COM ones for several reasons:

  1. This is easier to maintain. People that don't know COM much can focus on writing core classes and people who do know COM can safely wrap the core classes, without caring about the underlying implementation.

  2. Code reusability. This might not be a requirement for you, but since the core classes are decoupled from the COM ones, we case use them directly in C++ projects, where COM is not needed.

  3. Core testing. Since the logic is separated from the interface, you can proceed to minimal tests easily. You no longer wonder: "Where is my leak ? Is it a legitimate leak in my core logic or something related to COM?" Core classes can be tested independently and efficiently.

This increases both the number of files and the compilation time, but I (we) think it worth it.

ereOn
Yes these are essentially the thoughts prompting this question. But I was wondering about the implementation... in my approach there's the C++ core code, COM interface class (from IDL) and the COM implementation which inherits from the other two.
John
same in my place.
Alexandre C.
@John: We didn't use inheritance between `COM` classes and the core classes, mainly because it would have caused diamond-inheritance, which is *bad* imo. `COM` classes just wraps the core classes, and there is **no logic** elsewhere than in the core classes.
ereOn