Interface inheritance

M

Martin

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.
 
J

JKop

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
 
J

John Harrison

JKop said:
Martin posted:


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".



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.
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
 
J

John Harrison

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
 
M

Martin

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.



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

JKop

Should've written:

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


-JKop
 
R

red floyd

Martin said:
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<>.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top