Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do I re-use an interface implementation in many classes?
    primarykey
    data
    text
    <p>This question could also have been entitled "How to do reference-counting without ATL". Some similar questions have been asked <a href="https://stackoverflow.com/q/6507372/98903" title="Must the IUnknown interface be re-implemented by every new COM class?">here</a> and <a href="https://stackoverflow.com/q/10779834/98903" title="ATL COM - How To Reuse Code for Interface Method">here</a>, but in the former a different question was answered and in both cases, ATL is involved. My question is more general to C++ and not so much about COM.</p> <p>Suppose we have an <code>IUnknown</code> "interface", like so:</p> <pre><code>class IUnknown { public: virtual ULONG AddRef() = 0; virtual ULONG Release() = 0; virtual ULONG QueryInterface(void * iid, void **ppv) = 0; }; </code></pre> <p>...and let's throw in a few other interfaces that are part of a fictional SDK:</p> <pre><code>class IAnimal : public IUnknown { public: virtual IAnimal** GetParents() = 0; }; class IMammal : public IAnimal { public: virtual ULONG Reproduce() = 0; }; </code></pre> <p>Since I am going to be implementing several animals and mammals, I would rather not copy-paste the <code>AddRef()</code> and <code>Release()</code> implementations in every class, so I wrote <code>UnknownBase</code>:</p> <pre><code>class UnknownBase : public IUnknown { public: UnknownBase() { _referenceCount = 0; } ULONG AddRef() { return ++_referenceCount; } ULONG Release() { ULONG result = --_referenceCount; if (result == 0) { delete this; } return result; } private: ULONG _referenceCount; }; </code></pre> <p>...so that I may use it to, say, implement a <code>Cat</code>:</p> <pre><code>class Cat : public IMammal, UnknownBase { public: ULONG QueryInterface(void *, void**); IAnimal** GetParents(); ULONG Reproduce(); }; ULONG Cat::QueryInterface(void * iid, void **ppv) { // TODO: implement return E_NOTIMPL; } IAnimal** Cat::GetParents() { // TODO: implement return NULL; } ULONG Cat::Reproduce() { // TODO: implement return 0; } </code></pre> <p>...however, the compiler disagrees:</p> <pre><code>c:\path\to\farm.cpp(42): error C2259: 'Cat' : cannot instantiate abstract class due to following members: 'ULONG IUnknown::AddRef(void)' : is abstract c:\path\to\iunknown.h(8) : see declaration of 'IUnknown::AddRef' 'ULONG IUnknown::Release(void)' : is abstract c:\path\to\iunknown.h(9) : see declaration of 'IUnknown::Release' </code></pre> <p>What am I missing?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload