Archived

This topic is now archived and is closed to further replies.

HaywireGuy

COM: Chicken Interface

Recommended Posts

Nobody likes lengthy posts eh? Well I'll try to make this one short. So I have a base class for all the animals, IAnimal. And it's implementation, CAnimal. // ============================================================ class IAnimal : public IUnknown { public:     // IUnknown methods...     STDMETHOD (QueryInterface)(REFIID, LPVOID *) PURE;     STDMETHOD_ (ULONG, AddRef)() PURE;     STDMETHOD_ (ULONG, Release)() PURE;     // IAnimal methods...     STDMETHOD (Eat)(FOOD *) PURE;     STDMETHOD (Shit)() PURE; }; // ============================================================ class CAnimal : public IAnimal { public:     HRESULT QueryInterface(REFIID, LPVOID *);     ULONG AddRef();     ULONG Release();     HRESULT Eat(FOOD *);     HRESULT Shit(); }; Then I thought, hmm... why not I start by makin' a chicken object? So there I have it, IChicken, and its implementation, CChicken. Now it is obvious that IChicken is derived from IAnimal, so there you go... // ============================================================ class IChicken : public IAnimal { public:     // IUnknown methods...     STDMETHOD (QueryInterface)(REFIID, LPVOID *) PURE;     STDMETHOD_ (ULONG, AddRef)() PURE;     STDMETHOD_ (ULONG, Release)() PURE;     // IAnimal methods...     STDMETHOD (Eat)(FOOD *) PURE;     STDMETHOD (Shit)() PURE;     // IChicken specific methods...     STDMETHOD (Run)(INT) PURE; }; Now the problem comes. What would the CChiken implementation be? It should be derivin' from IChicken because it is supposed to implement the IChicken interface. But then it should also physically be derived from CAnimal since all the implementations have gone into CAnimal (Eat and Shit methods). So how should I start declarin' my CChiken class? Derived both from IChicken and CAnimal?! Hmmm... I'm waitin' for any hints that I might get, and thanks so much for your time.
[edited by - HaywireGuy on May 20, 2004 10:16:57 PM]

Share this post


Link to post
Share on other sites
What is the reason for IChicken? CChicken could implement IAnimal via deriving from CAnimal. There is no difference between IAnimal and IChicken.

Kuphryn

Share this post


Link to post
Share on other sites
kuphryn:

// IChicken specific methods...
STDMETHOD (Run)(INT) PURE;

IChicken provides a Run method.


[edited by - BlackHC on May 20, 2004 12:09:51 PM]

Share this post


Link to post
Share on other sites
CChicken : CAnimal, IChicken {} would not work? unsure..




If that''s not the help you''re after then you''re going to have to explain the problem better than what you have. - joanusdmentia

davepermen.net

Share this post


Link to post
Share on other sites
I would say that you''re thinking about it wrong ... I don''t see any reason for having the IChicken interface. Just implement the run Method in CChicken : CAnimal. If for some reason you need wild and new varieties of chicken, you can just CFunkyChicken : CChicken

Joel Martinez
http://www.codecube.net/

Share this post


Link to post
Share on other sites
If CChicken inherits CAnimal as it is I think the compiler will bitch at ya for inheriting IAnimal twice, so if you really must inherit the implementation you could make IChicken inherit IUnknown instead of IAnimal and CChicken could then inherit CAnimal without any problems. The annoying part about this is that given an IChicken pointer you would need to QI for IAnimal to access those methods.

Share this post


Link to post
Share on other sites
Just notice that you are defining you interfaces to have private member functions instead of public. Usually when working with COM people either use struct (as all the member functions should be public) or you can use the interface #define in the com headers (which is a #define for struct but makes it more clear that you are using it for a COM interface).

Share this post


Link to post
Share on other sites
I posted the question before I slept last night, and wow, when
I woke up I saw these many replies!! First, thanks guy, for
helpin' me. Now... one at a time:

Kuphryn, BlackHC,

Yes... IChicken has an additional method "Run". So CChicken has
to implement this "Run" method in it.

Pipo DeClown,

Hey how have you been dude? Anyway, like I said, CChicken has
another new method called "Run", so I not only needed stuff
from IAnimal, I need those from IChicken too.

davepermen,

That's what I thought of too, but I'm not sure will the final
VTable be screwed up because of this weird way of inheritance.

joelmartinez,

My client application needs to get an instance of CChicken too,
without IChicken interface, my client would be interactin' with
IAnimal directly, which does not tell the client that "Run"
method is supported in CChicken. As for the case of funky
chicken, I'll need IFunkyChicken for the same reason

Fragmo,

Okay, that's one way, but it does not change things much.
First, CChicken needs those implementations which have gone
into CAnimal (ie. Eat, Shit). Second, it needs to derive from
IChicken so that the "Run" method is exposed. So I'm not sure
if I'll end up with this...

    class CChicken : public IChicken, public CAnimal.

Will it work?

Polymorphic OOP,

Thanks man, I've forgotten those "public" in all my classes,
I've modified the post







[edited by - HaywireGuy on May 20, 2004 10:16:03 PM]

Share this post


Link to post
Share on other sites
Magmai Kai Holmlor, thanks for your reply. I'm not familiar
with template classes, maybe I need to pick it up soon. But
then is there no straight forward way to accomplish this task? If
there is no, then I'll go right down to read up some template stuff.

In your reply, you use both class and struct. I'm not sure but
won't it cause problem to even compile it? Thanks...








[edited by - HaywireGuy on May 20, 2004 12:58:18 AM]

Share this post


Link to post
Share on other sites
I FOUND THE SOLUTION!!!! This one is proven to work, so...
hooray!! There's a catch though, CChicken::Release() should not
call the base class's implementation because CAnimal::Release()
will call "delete this" and the thing will crash. Do "delete
this" in the derived class (ie. CChicken).


#include <Unknwn.h>

// ============================================================

class IAnimal : public IUnknown
{
    public:

    STDMETHOD (Eat)() PURE;
    STDMETHOD (Shit)() PURE;
};

// ============================================================

class IChicken : public IAnimal
{
    public:

    STDMETHOD (Run)() PURE;
};

// ============================================================

class CAnimal : public IAnimal
{
    public:

    CAnimal();
    ~CAnimal();

    // IUnknown method implementations.
    STDMETHODIMP QueryInterface(REFIID riid, LPVOID *lpvIntrfc);
    STDMETHODIMP_(ULONG) AddRef();
    STDMETHODIMP_(ULONG) Release();

    // IAnimal method implementations.
    STDMETHODIMP Eat();
    STDMETHODIMP Shit();

    protected:

    ULONG m_ulRefCount;
};

// ============================================================

class CChicken : public IChicken, public CAnimal
{
    public:

    CChicken();
    ~CChicken();

    // IUnknown method implementations.
    STDMETHODIMP QueryInterface(REFIID riid, LPVOID *lpvIntrfc);
    STDMETHODIMP_(ULONG) AddRef();
    STDMETHODIMP_(ULONG) Release();

    // IAnimal method implementations.
    STDMETHODIMP Eat();
    STDMETHODIMP Shit();

    // IChicken method implementations.
    STDMETHODIMP Run();
};







[edited by - HaywireGuy on May 21, 2004 3:58:16 AM]

Share this post


Link to post
Share on other sites