Interface inheritance

Discussion in 'C++' started by Martin, Nov 5, 2004.

  1. Martin

    Martin Guest

    Hi,

    Suppose I have 3 interfaces :

    IStats
    IEngine
    ICreateCar

    each derives from IUnknown

    then when I query object that implements those interfaces for IUnknown
    interface I need to do two casts:

    return (IUnknown*)(IStats*)this;

    Is there no difference if I would write : (IUnknown*)(IEngine*)this ? these
    are pure abstract interfaces, only pure virtual methods, suppose I had there
    some data, would it then make any difference?

    Thanks for any help, my COM book just dont get too deep with C++ OOP.
    Martin, Nov 5, 2004
    #1
    1. Advertising

  2. Martin

    JKop Guest

    Martin posted:

    > Hi,
    >
    > Suppose I have 3 interfaces :


    By "interface", I'm assuming you mean:

    A class,

    - which has no member variables or member objects.

    - which has no member functions, except pure virtual ones.

    - which is not derived from any class which qualifies as an
    "interface".


    > IStats
    > IEngine
    > ICreateCar
    >
    > each derives from IUnknown
    >
    > then when I query an object that implements those interfaces for IUnknown
    > interface I need to do two casts:
    >
    > return (IUnknown*)(IStats*)this;


    By "query", I'm assuming you mean either

    A) Access a member variable or member object.

    B) Access a member function.


    You don't need those casts. Take them out and (try) compile it. If the
    classes trully are derived from one another, then it will work.


    > Is there no difference if I would write : (IUnknown*)(IEngine*)this ?
    > these are pure abstract interfaces, only pure virtual methods, suppose
    > I had there some data, would it then make any difference?


    Again casting is not necessary if the classes are derived from one another.


    Let's say for instance that the casts *were* necessary, ie. that
    "IPowerfulEngine" was not actually derived from "IEngine", like as follows:

    class IEngine : public IUnknown {};

    class IPowerfulEngine {};


    Even in this case, in writing:

    SomeFunc( (IUnknown*)(IEngine*)&powerful_engine_object );

    You're just wasting your time typing.

    What you *could* have written was simply:

    (IUnknown*)&powerful_engine_object;

    or better:

    reinterpret_cast< IUnknown* > (&powerful_engine_object);


    -JKop
    JKop, Nov 5, 2004
    #2
    1. Advertising

  3. "JKop" <> wrote in message
    news:ZpIid.40967$...
    > Martin posted:
    >
    > > Hi,
    > >
    > > Suppose I have 3 interfaces :

    >
    > By "interface", I'm assuming you mean:
    >
    > A class,
    >
    > - which has no member variables or member objects.
    >
    > - which has no member functions, except pure virtual ones.
    >
    > - which is not derived from any class which qualifies as an
    > "interface".
    >
    >
    > > IStats
    > > IEngine
    > > ICreateCar
    > >
    > > each derives from IUnknown
    > >
    > > then when I query an object that implements those interfaces for

    IUnknown
    > > interface I need to do two casts:
    > >
    > > return (IUnknown*)(IStats*)this;

    >
    > By "query", I'm assuming you mean either
    >
    > A) Access a member variable or member object.
    >
    > B) Access a member function.
    >
    >
    > You don't need those casts. Take them out and (try) compile it. If the
    > classes trully are derived from one another, then it will work.
    >


    You do need (IStats*) because IStats, IEngine and ICreateCar all derive from
    IUnknown so the conversion is ambiguous without any casts. But you don't
    need the (IUnknown*) cast.

    >
    > > Is there no difference if I would write : (IUnknown*)(IEngine*)this ?
    > > these are pure abstract interfaces, only pure virtual methods, suppose
    > > I had there some data, would it then make any difference?

    >
    > Again casting is not necessary if the classes are derived from one

    another.
    >


    The OP has multiple IUnknown objects, so if those objects had some state
    then it could make a difference.

    john
    John Harrison, Nov 5, 2004
    #3
  4. >
    > Thanks for any help, my COM book just dont get too deep with C++ OOP.
    >


    Buy 'Understanding COM' by Don Box. It sounds like it is exactly what you
    need. It is also the COM book for C++ programmers.

    john
    John Harrison, Nov 5, 2004
    #4
  5. Martin

    Martin Guest

    U¿ytkownik "JKop" <> napisa³ w wiadomo¶ci
    news:ZpIid.40967$...

    > By "interface", I'm assuming you mean:
    >
    > A class,
    >
    > - which has no member variables or member objects.
    > - which has no member functions, except pure virtual ones.
    > - which is not derived from any class which qualifies as an
    > "interface".


    Actually it can derive from other interfaces, and I think this is why those
    casts are needed, this is multiple inheritance with some of the base classes
    being the same (like IUnknown).

    > By "query", I'm assuming you mean either
    >
    > A) Access a member variable or member object.
    >
    > B) Access a member function.


    By query I mean to cast object to one of its base classes (interfaces)

    > You don't need those casts. Take them out and (try) compile it. If the
    > classes trully are derived from one another, then it will work.
    >
    >
    >> Is there no difference if I would write : (IUnknown*)(IEngine*)this ?
    >> these are pure abstract interfaces, only pure virtual methods, suppose
    >> I had there some data, would it then make any difference?

    >
    > Again casting is not necessary if the classes are derived from one
    > another.
    >
    >
    > Let's say for instance that the casts *were* necessary, ie. that
    > "IPowerfulEngine" was not actually derived from "IEngine", like as
    > follows:
    >
    > class IEngine : public IUnknown {};
    >
    > class IPowerfulEngine {};
    >
    >
    > Even in this case, in writing:
    >
    > SomeFunc( (IUnknown*)(IEngine*)&powerful_engine_object );
    >
    > You're just wasting your time typing.
    >
    > What you *could* have written was simply:
    >
    > (IUnknown*)&powerful_engine_object;


    Yes, but base classes (interfaces) of powerful_engine_object class all
    derive from IUnknown. So I think compiler just wants clarification to
    resolve ambiguous situation. Here is some code :

    //
    class IStats : public IUnknown
    {};
    class IEngine : public IUnknown
    {};
    class CoCar : public IEngine, IStats
    {};

    //
    STDMETHODIMP CoCar::QueryInterface(REFIID riid, void **ppvInt)
    {
    *ppvInt = NULL;
    if (riid == IID_IUnknown)
    {
    *ppvInt = (IUnknown*)(IEngine*)this; //this is ok

    //*ppvInt = (IUnknown*)this;
    // gives : error C2594: 'type cast' : ambiguous conversions from
    'CoCar *const ' to 'IUnknown *'
    }
    else if (riid == IID_IStats)
    {
    *ppvInt = (IStats*)this;
    }
    else if (riid == IID_IEngine)
    {
    *ppvInt = (IEngine*)this;
    }
    ((IUnknown*)(*ppvInt))->AddRef();
    return S_OK;
    }
    Martin, Nov 5, 2004
    #5
  6. Martin

    JKop Guest


    >> - which is not derived from any class which qualifies as an
    >> "interface".



    Should've written:

    - which is not derived from any class which does not qualifiy as an
    "interface".


    -JKop
    JKop, Nov 5, 2004
    #6
  7. Martin

    red floyd Guest

    Martin wrote:
    > Hi,
    >
    > Suppose I have 3 interfaces :
    >
    > IStats
    > IEngine
    > ICreateCar
    >
    > each derives from IUnknown
    >
    > then when I query object that implements those interfaces for IUnknown
    > interface I need to do two casts:
    >
    > return (IUnknown*)(IStats*)this;
    >
    > Is there no difference if I would write : (IUnknown*)(IEngine*)this ? these
    > are pure abstract interfaces, only pure virtual methods, suppose I had there
    > some data, would it then make any difference?
    >
    > Thanks for any help, my COM book just dont get too deep with C++ OOP.
    >
    >


    As a side note, do not, repeat DO NOT use C-style casts in this sort of
    situation. You need to use static_cast<> or dynamic_cast<>.
    red floyd, Nov 5, 2004
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Wildepiet
    Replies:
    0
    Views:
    1,860
    Wildepiet
    Jun 14, 2004
  2. cyberco
    Replies:
    8
    Views:
    487
    cyberco
    Feb 25, 2006
  3. Xah Lee
    Replies:
    15
    Views:
    583
    Sherm Pendley
    Mar 23, 2007
  4. Xah Lee
    Replies:
    15
    Views:
    629
    Sherm Pendley
    Mar 23, 2007
  5. Daniel Pitts
    Replies:
    27
    Views:
    1,896
    Mike Schilling
    Feb 27, 2008
Loading...

Share This Page