1

この質問は、「ATL を使用せずに参照カウントを行う方法」というタイトルになっている可能性もあります。いくつかの同様の質問がここここで尋ねられていますが、前者では別の質問が回答されており、どちらの場合も ATL が関与しています。私の質問は、COM についてではなく、C++ についてより一般的です。

IUnknown次のような「インターフェース」があるとします。

class IUnknown
{
public:
    virtual ULONG AddRef() = 0;
    virtual ULONG Release() = 0;
    virtual ULONG QueryInterface(void * iid, void **ppv) = 0;
};

...そして、架空の SDK の一部である他のいくつかのインターフェイスを投入しましょう。

class IAnimal : public IUnknown
{
public:
    virtual IAnimal** GetParents() = 0;
};

class IMammal : public IAnimal
{
public:
    virtual ULONG Reproduce() = 0;
};

私はいくつかの動物と哺乳類を実装しようとしているので、すべてのクラスでAddRef()andのRelease()実装をコピーして貼り付けたくないので、次のように書きましたUnknownBase:

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

...それを使用して、たとえば、次を実装できるようにしますCat

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

...しかし、コンパイラは同意しません:

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'

私は何が欠けていますか?

4

3 に答える 3

1

これには、インターフェース定義を変更する必要はありません。

template<class I>
class UnknownBase : public I
{
    ...
}

class Cat : public UnknownBase<IMammal>
{
    ...
}
于 2013-06-26T16:01:42.467 に答える
0

仮想基本クラスを使用して継承する必要があります。変化する:

クラス IAnimal : public IUnknown --> クラス IAnimal : public virtual IUnknown; と

クラス UnknownBase : public IUnknown --> クラス UnknownBase : public virtual IUnknown

于 2013-06-26T03:53:41.663 に答える