By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
431,852 Members | 2,116 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 431,852 IT Pros & Developers. It's quick & easy.

Interface implementation

P: n/a
Hi all. I have some questions about interface implementation, if
anybody can help me, I will be very thank.
So:

If i have some interface IA:

class IA
{
virtual void SomePureVirtFunc() = 0;
};

and some class B, that implemented that interface:

class B : public IA
{
virtual void SomePureVirtFunc() {};
};

Now I need in class C inherit from interface ITwoInOne, that inherited
from IA also.
Question: it is any method, inherit from interface ITwoInOne, and
don't implement interface IA, but using multiple inheritance - inherit
from class B, that already implemented that interface, and satisfy my
requirements?

Another words: can I write something like that:

class NewOne : public B
, public ITwoInOne
{
//Implementation only pure virtual functions
//, that not correspond to IA interface
}

P.S. sorry for confusion, and for my bad English.

Jun 14 '07 #1
Share this Question
Share on Google+
17 Replies


P: n/a
Galian wrote:
Hi all. I have some questions about interface implementation, if
anybody can help me, I will be very thank.
So:

If i have some interface IA:

class IA
{
virtual void SomePureVirtFunc() = 0;
};

and some class B, that implemented that interface:

class B : public IA
{
virtual void SomePureVirtFunc() {};
};

Now I need in class C inherit from interface ITwoInOne, that inherited
from IA also.
Question: it is any method, inherit from interface ITwoInOne, and
don't implement interface IA, but using multiple inheritance - inherit
from class B, that already implemented that interface, and satisfy my
requirements?
Yes, inherit from IA _virtually_ *everywhere*. I.e. make B inherit from
IA virtually and make ITwoInOne inherit virtually.
>
Another words: can I write something like that:

class NewOne : public B
, public ITwoInOne
{
//Implementation only pure virtual functions
//, that not correspond to IA interface
}

P.S. sorry for confusion, and for my bad English.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 14 '07 #2

P: n/a
Yes, inherit from IA _virtually_ *everywhere*. I.e. make B inherit from
IA virtually and make ITwoInOne inherit virtually.
So this is right way:

class B : public virtual IA
{

};

class NewOne : public virtual B
, public virtual ITwoInOne
{

};

Is this right?
If yes, than question: is order of classes for inheritance important?
I mean it is OK if I write first "public virtual ITwoInOne", and than
"public virtual B"?

Jun 14 '07 #3

P: n/a
Galian wrote:
>Yes, inherit from IA _virtually_ *everywhere*. I.e. make B inherit
from IA virtually and make ITwoInOne inherit virtually.

So this is right way:

class B : public virtual IA
{

};

class NewOne : public virtual B
, public virtual ITwoInOne
{

};

Is this right?
If yes, than question: is order of classes for inheritance important?
I mean it is OK if I write first "public virtual ITwoInOne", and than
"public virtual B"?
I think that the order is not significant. Have you tried it? If you
have, and the success depended on the order, could you please share?
If you haven't tried, why?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 14 '07 #4

P: n/a
I have tried, and it don't work. "Cannot instantiate abstract class"
error. I don't now why. I tried different order, but it don't help.
Thank you Victor for the answers.

Jun 14 '07 #5

P: n/a
Galian wrote:
I have tried, and it don't work. "Cannot instantiate abstract class"
error. I don't now why. I tried different order, but it don't help.
Sounds like FAQ 5.8 should help. Check it out. It also can be that
your compiler is not capable; we'll know as you check out the FAQ.
Thank you Victor for the answers.
You're most welcome.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 14 '07 #6

P: n/a

Victor Bazarov :
Galian wrote:
I have tried, and it don't work. "Cannot instantiate abstract class"
error. I don't now why. I tried different order, but it don't help.

Sounds like FAQ 5.8 should help. Check it out. It also can be that
your compiler is not capable; we'll know as you check out the FAQ.
Thank you Victor for the answers.

You're most welcome.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sorry Victor, but about what FAQ you talking? Where can I find it?

Jun 14 '07 #7

P: n/a
Galian wrote:
Victor Bazarov :
>Galian wrote:
>>I have tried, and it don't work. "Cannot instantiate abstract class"
error. I don't now why. I tried different order, but it don't help.
Sounds like FAQ 5.8 should help. Check it out. It also can be that
your compiler is not capable; we'll know as you check out the FAQ.

Sorry Victor, but about what FAQ you talking? Where can I find it?
C++ FAQ: http://www.parashift.com/c++-faq-lite
FAQ 5.8: http://www.parashift.com/c++-faq-lit...t.html#faq-5.8
Jun 14 '07 #8

P: n/a
Galian wrote:
Victor Bazarov :
>[..] check out the FAQ.
[..]
Sorry Victor, but about what FAQ you talking? Where can I find it?
Is that your first day here?

http://www.parashift.com/c++-faq-lite/

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 14 '07 #9

P: n/a
Sorry Victor, but about what FAQ you talking? Where can I find it?

Wow, I understand :) sorry.

This is my code. Task is next: I want write template class, CUnknown,
with implemented nessesary methods (Queryinterface, Release ...), to
use it for other classes.

CUnknown:

template < class ClassType, REFIID ObjectIID >
class CUnknown : public IUnknown
{
protected:
// IUnknown methods.
virtual STDMETHODIMP QueryInterface( REFIID riid, void** ppv )
{
if ( ppv == NULL )
{
return E_POINTER;
}
if ( riid == *ObjectIID || riid == IID_IUnknown )
{
*ppv = static_cast< ClassType* >( this );
AddRef();
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}

virtual STDMETHODIMP_( ULONG ) AddRef()
{
return InterlockedIncrement( &m_cRef );
}

virtual STDMETHODIMP_( ULONG ) Release()
{
LSCOPE( "CMediaBuffer::Release" );
LONG lRef = InterlockedDecrement( &m_cRef );
if ( lRef == 0 )
{
delete this;

// m_cRef is no longer valid! Return lRef.
}
return lRef;
}

LONG m_cRef;
};

#include "Unknown.h"

class ISMSNotificationHandler
{
public:
virtual void HandleSMSMessageReceived( const CEOID messageID ) = 0;
};

// IMAPIAdviseSink also derived from IUnknown

class CAdviseSinc
// This is my CUnknown,but anyway "Cannot instantiate abstract
class" error
: public virtual CUnknown< CAdviseSinc, IID_IMAPIAdviseSink >
, public virtual IMAPIAdviseSink
{
public:
CAdviseSinc();
~CAdviseSinc();

private:
ULONG OnNotify( ULONG cNotif, LPNOTIFICATION lpNotifications );
};
>>Is that your first day here?
Actually in this group yes, but not in other, I am sorry.

Jun 14 '07 #10

P: n/a
Galian wrote:
[..]
This is my code. Task is next: I want write template class, CUnknown,
with implemented nessesary methods (Queryinterface, Release ...), to
use it for other classes.

CUnknown:

template < class ClassType, REFIID ObjectIID >
class CUnknown : public IUnknown
What's "IUnknown"? Are we supposed to know about it? (pun intended)
I am guessing that it's the base interface you have and it's abstract.
{
protected:
// IUnknown methods.
virtual STDMETHODIMP QueryInterface( REFIID riid, void** ppv )
{
if ( ppv == NULL )
{
return E_POINTER;
}
if ( riid == *ObjectIID || riid == IID_IUnknown )
{
*ppv = static_cast< ClassType* >( this );
AddRef();
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}

virtual STDMETHODIMP_( ULONG ) AddRef()
{
return InterlockedIncrement( &m_cRef );
}

virtual STDMETHODIMP_( ULONG ) Release()
{
LSCOPE( "CMediaBuffer::Release" );
LONG lRef = InterlockedDecrement( &m_cRef );
if ( lRef == 0 )
{
delete this;

// m_cRef is no longer valid! Return lRef.
}
return lRef;
}

LONG m_cRef;
};

#include "Unknown.h"
I am guessing that's where your 'class CUnknown' is defined, or is it?
>
class ISMSNotificationHandler
{
public:
virtual void HandleSMSMessageReceived( const CEOID messageID ) = 0;
};

// IMAPIAdviseSink also derived from IUnknown

class CAdviseSinc
// This is my CUnknown,but anyway "Cannot instantiate abstract
class" error
Does it say what function prevents it from being instantiated?
>public virtual CUnknown< CAdviseSinc, IID_IMAPIAdviseSink >
, public virtual IMAPIAdviseSink
{
public:
CAdviseSinc();
~CAdviseSinc();

private:
ULONG OnNotify( ULONG cNotif, LPNOTIFICATION lpNotifications );
};
OK. Try to change the beginning of the definition of 'CUnknown' to

template < class ClassType, REFIID ObjectIID >
class CUnknown : virtual public IUnknown
^^^^^^^

Also, do the same with IMAPIAdviseSink. What you're doing is telling
the compiler that some pure virtual functions in your 'CAdviseSink'
only exist in a single base class instance and that they are happily
overridden by the corresponding functions in 'CUnknown<blah,blah>'.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 14 '07 #11

P: n/a
Ok, this is my code now:

//CUnknow class

template < class ClassType, REFIID ObjectIID >
class CUnknown : public IUnknown
{
protected:
// IUnknown methods.
virtual STDMETHODIMP QueryInterface( REFIID riid, void** ppv )
{
if ( ppv == NULL )
{
return E_POINTER;
}
if ( riid == ObjectIID || riid == IID_IUnknown )
{
*ppv = reinterpret_cast< ClassType* >( this );
AddRef();
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}

virtual STDMETHODIMP_( ULONG ) AddRef()
{
return InterlockedIncrement( &m_cRef );
}

virtual STDMETHODIMP_( ULONG ) Release()
{
LONG lRef = InterlockedDecrement( &m_cRef );
if ( lRef == 0 )
{
delete this;
// m_cRef is no longer valid! Return lRef.
}
return lRef;
}

LONG m_cRef;
};

// IMAPIAdviseSink also derived from IUnknown

class CAdviseSinc
: public virtual CUnknown< CAdviseSinc, IID_IMAPIAdviseSink >
, public virtual IMAPIAdviseSink
{
public:
CAdviseSinc() {};
~CAdviseSinc() {};

private:

ULONG OnNotify( ULONG cNotif, LPNOTIFICATION lpNotifications )
{ return 0; }
};

Now,if I try to create instance of class CAdviseSinc, i have this
message:

error C2259: 'CAdviseSinc' : cannot instantiate abstract class
due to following members:
'HRESULT IMAPIAdviseSink::QueryInterface(const IID &,LPVOID
*)' : is abstract
C:\Program Files\Windows CE Tools\wce500\Windows Mobile 5.0
Pocket PC SDK\include\ARMV4I\mapidefs.h(889) : see declaration of
'IMAPIAdviseSink::QueryInterface'
'ULONG IMAPIAdviseSink::AddRef(void)' : is abstract
C:\Program Files\Windows CE Tools\wce500\Windows Mobile 5.0
Pocket PC SDK\include\ARMV4I\mapidefs.h(889) : see declaration of
'IMAPIAdviseSink::AddRef'
'ULONG IMAPIAdviseSink::Release(void)' : is abstract
C:\Program Files\Windows CE Tools\wce500\Windows Mobile 5.0
Pocket PC SDK\include\ARMV4I\mapidefs.h(889) : see declaration of
'IMAPIAdviseSink::Release'

but this three methods are implemented in CUnknown.

Jun 14 '07 #12

P: n/a
Galian wrote:
Ok, this is my code now:

//CUnknow class

template < class ClassType, REFIID ObjectIID >
class CUnknown : public IUnknown
I am sorry to sound a bit irritated, but didn't I just tell
you to use virtual inheritance *here* AND in the *definition*
of 'IMAPIAdviseSink'? You decided NOT TO follow that and
instead derived virtualy *from* 'IMAPIAdviseSink'. Am I just
being unclear somehow?
{
protected:
// IUnknown methods.
virtual STDMETHODIMP QueryInterface( REFIID riid, void** ppv )
{
if ( ppv == NULL )
{
return E_POINTER;
}
if ( riid == ObjectIID || riid == IID_IUnknown )
{
*ppv = reinterpret_cast< ClassType* >( this );
AddRef();
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}

virtual STDMETHODIMP_( ULONG ) AddRef()
{
return InterlockedIncrement( &m_cRef );
}

virtual STDMETHODIMP_( ULONG ) Release()
{
LONG lRef = InterlockedDecrement( &m_cRef );
if ( lRef == 0 )
{
delete this;
// m_cRef is no longer valid! Return lRef.
}
return lRef;
}

LONG m_cRef;
};

// IMAPIAdviseSink also derived from IUnknown

class CAdviseSinc
>public virtual CUnknown< CAdviseSinc, IID_IMAPIAdviseSink >
, public virtual IMAPIAdviseSink
{
public:
CAdviseSinc() {};
~CAdviseSinc() {};

private:

ULONG OnNotify( ULONG cNotif, LPNOTIFICATION lpNotifications )
{ return 0; }
};

Now,if I try to create instance of class CAdviseSinc, i have this
message:

error C2259: 'CAdviseSinc' : cannot instantiate abstract class
due to following members:
'HRESULT IMAPIAdviseSink::QueryInterface(const IID &,LPVOID
*)' : is abstract
C:\Program Files\Windows CE Tools\wce500\Windows Mobile 5.0
Pocket PC SDK\include\ARMV4I\mapidefs.h(889) : see declaration of
'IMAPIAdviseSink::QueryInterface'
'ULONG IMAPIAdviseSink::AddRef(void)' : is abstract
C:\Program Files\Windows CE Tools\wce500\Windows Mobile 5.0
Pocket PC SDK\include\ARMV4I\mapidefs.h(889) : see declaration of
'IMAPIAdviseSink::AddRef'
'ULONG IMAPIAdviseSink::Release(void)' : is abstract
C:\Program Files\Windows CE Tools\wce500\Windows Mobile 5.0
Pocket PC SDK\include\ARMV4I\mapidefs.h(889) : see declaration of
'IMAPIAdviseSink::Release'

but this three methods are implemented in CUnknown.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 14 '07 #13

P: n/a

Victor Bazarov :
Galian wrote:
Ok, this is my code now:

//CUnknow class

template < class ClassType, REFIID ObjectIID >
class CUnknown : public IUnknown

I am sorry to sound a bit irritated, but didn't I just tell
you to use virtual inheritance *here* AND in the *definition*
of 'IMAPIAdviseSink'? You decided NOT TO follow that and
instead derived virtualy *from* 'IMAPIAdviseSink'. Am I just
being unclear somehow?
Sorry I forgot it, fixed, now CUnknown look like it:

template < class ClassType, REFIID ObjectIID >
class CUnknown : public virtual IUnknown
{
..
..
..
but error message the same as before

Jun 14 '07 #14

P: n/a
Galian wrote:
Victor Bazarov :
>Galian wrote:
>>Ok, this is my code now:

//CUnknow class

template < class ClassType, REFIID ObjectIID >
class CUnknown : public IUnknown

I am sorry to sound a bit irritated, but didn't I just tell
you to use virtual inheritance *here* AND in the *definition*
of 'IMAPIAdviseSink'? You decided NOT TO follow that and
instead derived virtualy *from* 'IMAPIAdviseSink'. Am I just
being unclear somehow?

Sorry I forgot it, fixed, now CUnknown look like it:

template < class ClassType, REFIID ObjectIID >
class CUnknown : public virtual IUnknown
{
.
.
.
but error message the same as before
OK. Let's put your code aside for a minute. Try the following:
------------------
class I { virtual void foo() = 0; };
class C : virtual public I { void foo() {} };
class II : virtual public I {};
class CC : public C, public II {};

int main() {
CC cc;
}
------------------
Does it compile with your compiler? If it doesn't, your compiler is
non-compliant and you will have to work around its shortcomings. You
will need to re-implement the "offending" functions in the final class
and in them simply call the one you want to work as the overrider.

If the code does compile, please study it and make the necessary changes
to *your* code.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 14 '07 #15

P: n/a

Victor Bazarov :
Galian wrote:
Victor Bazarov :
Galian wrote:
Ok, this is my code now:

//CUnknow class

template < class ClassType, REFIID ObjectIID >
class CUnknown : public IUnknown

I am sorry to sound a bit irritated, but didn't I just tell
you to use virtual inheritance *here* AND in the *definition*
of 'IMAPIAdviseSink'? You decided NOT TO follow that and
instead derived virtualy *from* 'IMAPIAdviseSink'. Am I just
being unclear somehow?
Sorry I forgot it, fixed, now CUnknown look like it:

template < class ClassType, REFIID ObjectIID >
class CUnknown : public virtual IUnknown
{
.
.
.
but error message the same as before

OK. Let's put your code aside for a minute. Try the following:
------------------
class I { virtual void foo() = 0; };
class C : virtual public I { void foo() {} };
class II : virtual public I {};
class CC : public C, public II {};

int main() {
CC cc;
}
------------------
Does it compile with your compiler? If it doesn't, your compiler is
non-compliant and you will have to work around its shortcomings. You
will need to re-implement the "offending" functions in the final class
and in them simply call the one you want to work as the overrider.

If the code does compile, please study it and make the necessary changes
to *your* code.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Yes it compiled, only warning "warning C4250: 'CC' : inherits
'C::C::foo' via dominance
.\ConsoleSmart.cpp(45) : see declaration of 'C::foo'"

Thank you very much. Sorry for the trouble.

Jun 14 '07 #16

P: n/a
On Jun 14, 3:32 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Galian wrote:
Yes, inherit from IA _virtually_ *everywhere*. I.e. make B inherit
from IA virtually and make ITwoInOne inherit virtually.
So this is right way:
class B : public virtual IA
{
};
class NewOne : public virtual B
, public virtual ITwoInOne
{
};
Is this right?
If ITwoInOne inherits from IA, it must also inherit virtually.
If NewOne is the most derived class, on the other hand, virtual
inheritance from B and from ITwoInOne is not necessary, although
it may be a good idea, in case someone later wants to inherit
from it. (In general, unless the inheritance tree is closed,
most inhertance should be virtual.)
If yes, than question: is order of classes for inheritance important?
I mean it is OK if I write first "public virtual ITwoInOne", and than
"public virtual B"?
I think that the order is not significant.
It affects the order in which constructors are called. In the
case of virtual base classes, the constructors are called from
the most derived class, "in the order they appear on a
depth-first left-to-right traversal of the directed acyclic
graph of base classes, where `left-to-right' is the order of
appearance of the base class names in the derived class
base-specifierlist."

It will also typically affect the actual layout, and may have
some effect on runtime, although I can't imagine this being
significant.
Have you tried it? If you
have, and the success depended on the order, could you please share?
If you haven't tried, why?
Note that trying it doesn't tell you anything about the
guarantee. The order you find might be because in the standard,
the order was implementation defined, or unspecified.
Experimentation is usually a pretty poor means of finding out
these sort of things; the poster is doing the right thing in
asking.

--
James Kanze (GABI Software, from CAI) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 15 '07 #17

P: n/a
James Kanze wrote:
On Jun 14, 3:32 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>Have you tried it? If you
have, and the success depended on the order, could you please share?
If you haven't tried, why?

Note that trying it doesn't tell you anything about the
guarantee.
No, but it gets him closer to _a_ solution so he can move onto more
important things in life than looking for guarantees.
The order you find might be because in the standard,
the order was implementation defined, or unspecified.
Is it?
Experimentation is usually a pretty poor means of finding out
these sort of things; the poster is doing the right thing in
asking.
<sighMaybe, in this particular case. I am not sure what you
mean by "these sort of things", though. WHAT sort of things?

I say, push that "compile" button without asking first, since
nothing bad can come out of it, really. There is no sense in
asking "will such and such code compile?" when you have a compiler
sitting right there. One could ask "_should_ such and such code
compile" or "is my compiler correct to {accept/reject} such and
such code", but I still don't see a reason not to try.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 15 '07 #18

This discussion thread is closed

Replies have been disabled for this discussion.