Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > problem regarding inheritance

Reply
Thread Tools

problem regarding inheritance

 
 
frank_skare@yahoo.de
Guest
Posts: n/a
 
      02-10-2008
Hello everybody,
I'm writing a COM component and don't want to put the IUnknown
implementation in every COM class so I'm using inheritance. I'm
getting a error 'cannot instantiate abstract class' even though all
virtual methods are implemented. Can anybody tell me what I'm doing
wrong?

thanks
Frank


#include "stdafx.h"
#include <shlobj.h>

class ComBase
{
public:
STDMETHOD(QueryInterface)(REFIID,LPVOID*);

STDMETHODIMP_(ULONG) AddRef()
{
return 0;
}

STDMETHODIMP_(ULONG) Release()
{
return 0;
}
};

class ComClass: public ComBase, public IShellExtInit
{
public:
STDMETHOD(QueryInterface)(REFIID,LPVOID*);
STDMETHOD(Initialize)(LPCITEMIDLIST, LPDATAOBJECT, HKEY);
};

STDMETHODIMP ComClass::QueryInterface(REFIID riid, LPVOID *ppv)
{
return E_NOTIMPL;
}

STDMETHODIMP ComClass::Initialize(
LPCITEMIDLIST pidlFolder,
LPDATAOBJECT pDataObj,
HKEY hProgID
)
{
return E_NOTIMPL;
}

int _tmain(int argc, _TCHAR* argv[])
{
ComClass argh;
return 0;
}
 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      02-10-2008
* http://www.velocityreviews.com/forums/(E-Mail Removed):
> Hello everybody,
> I'm writing a COM component and don't want to put the IUnknown
> implementation in every COM class so I'm using inheritance. I'm
> getting a error 'cannot instantiate abstract class' even though all
> virtual methods are implemented. Can anybody tell me what I'm doing
> wrong?



Regarding the code below, it would be much better if you made an attempt
at presenting your problem in standard C++.


> #include "stdafx.h"
> #include <shlobj.h>


The headers above are not standard C++ headers.


> class ComBase
> {
> public:
> STDMETHOD(QueryInterface)(REFIID,LPVOID*);
>
> STDMETHODIMP_(ULONG) AddRef()
> {
> return 0;
> }
>
> STDMETHODIMP_(ULONG) Release()
> {
> return 0;
> }
> };


These macros are not standard C++.



> class ComClass: public ComBase, public IShellExtInit
> {
> public:
> STDMETHOD(QueryInterface)(REFIID,LPVOID*);
> STDMETHOD(Initialize)(LPCITEMIDLIST, LPDATAOBJECT, HKEY);
> };
>
> STDMETHODIMP ComClass::QueryInterface(REFIID riid, LPVOID *ppv)
> {
> return E_NOTIMPL;
> }
>
> STDMETHODIMP ComClass::Initialize(
> LPCITEMIDLIST pidlFolder,
> LPDATAOBJECT pDataObj,
> HKEY hProgID
> )
> {
> return E_NOTIMPL;
> }
>
> int _tmain(int argc, _TCHAR* argv[])


In standard C++ you need (minimum)

int main()



> {
> ComClass argh;
> return 0;
> }



Rephrasing your problem in standard C++, you have code that is analogous to

struct IUnknown
{
virtual void unkFuncA() = 0;
virtual void unkFuncB() = 0;
virtual void unkFuncC() = 0;
};

struct IShellExtInit: IUnknown
{
virtual void seiFunc() = 0;
};

struct ComBase
{
virtual void unkFuncA() = 0;
void unkFuncB() {}
void unkFuncC() {}
};

struct ComClass: ComBase, IShellExtInit
{
void unkFuncA() {}
void seiFunc() {}
};

int main()
{
ComClass o; // Oops, doesn't compile.
}

ComClass inherits from ComBase and implements the single pure virtual
ComBase function unkFunkA. That's technically OK, although it doesn't
achieve the purpose of implementing IUnknown.

ComClass also inherits from IShellExtInit. I ShellExtInit has four pure
virtual functions, one it declares itself and three inherited from
IUnknown. ComClass implements two of them, seiFunc() and unkFuncA().

That leaves two pure virtual functions in ComClass, which means ComClass
is non-instantiable, an abstract class.

There are many ways to approach the problem of providing a stock
IUnknown implementation.

From a pure C++ point of view the most elegant and simple is to use
virtual inheritance to inherit in an implementation. However, that is
almost impossible to retrofit, since in your case ISHellExtInit is given
and presumably does not inherit virtually from IUnknown. An alternative
is then to use a templated bottom-level class, like

struct IUnknown
{
virtual void unkFuncA() = 0;
virtual void unkFuncB() = 0;
virtual void unkFuncC() = 0;
};

struct IShellExtInit: IUnknown
{
virtual void seiFunc() = 0;
};

template< class Base >
struct UnknownImpl: Base
{
void unkFuncA() {}
void unkFuncB() {}
void unkFuncC() {}
};

struct AbstractComClass: IShellExtInit
{
void seiFunc() {}
};

typedef UnknownImpl<AbstractComClass> ComClass;

int main()
{
ComClass o; // OK.
}

This is the technique used in the ATL and WTL libraries.


Cheers, & hth.,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Query regarding java Multiple Inheritance Amit Jain Java 7 11-28-2009 08:59 AM
Design question regarding inheritance/polymorphism Angus C++ 3 01-04-2009 05:40 PM
Doubt regarding Virtual Inheritance Anarki C++ 5 07-07-2007 09:04 AM
Question regarding class inheritance He Shiming C++ 2 06-10-2005 02:06 PM
Doubt regarding inheritance involving templates darkstorm C++ 3 03-29-2005 07:10 AM



Advertisments