开始C ++问题;无法实例化抽象类(VS中的C2259)

时间:2009-03-29 20:43:22

标签: c++ windows com

我正在尝试创建IAudioEvents COM接口的具体实例(在Vista及更高版本中可用)。这是我第一次涉足COM编程,所以我可能只是在做一些愚蠢的事情。无论如何,以下代码无法使用“C2259:'AudioEndpointVolumeNotifierImpl'进行编译:无法实例化抽象类”。

Class Definiton(AudioEndpointVolumeNotifierImpl.h):

class AudioEndpointVolumeNotifierImpl : public IAudioSessionEvents
{
private:
    LONG _cRef;

public:
    AudioEndpointVolumeNotifierImpl() : _cRef(1){}
    ~AudioEndpointVolumeNotifierImpl(){}
    HRESULT STDMETHODCALLTYPE OnSimpleVolumeChanged(float NewVolume, BOOL NewMute,LPCGUID EventContext);

    HRESULT STDMETHODCALLTYPE OnChannelVolumeChanged(DWORD ChannelCount, float NewChannelVolumeArray[], DWORD ChangedChannel, LPCGUID EventContext){return S_OK;}
    HRESULT STDMETHODCALLTYPE OnDisplayNameChanged(LPCWSTR NewDisplayName, LPCGUID EventContext){return S_OK;}
    HRESULT STDMETHODCALLTYPE OnGroupingParamChanged(LPCGUID NewGroupingParam, LPCGUID EventContext){return S_OK;}
    HRESULT STDMETHODCALLTYPE OnIconPathChanged(LPWCHAR NewIconPath, LPCGUID EventContext){return S_OK;}
    HRESULT STDMETHODCALLTYPE OnSessionDisconnected(AudioSessionDisconnectReason DisconnectReason){return S_OK;}
    HRESULT STDMETHODCALLTYPE OnStateChanged(AudioSessionState NewState){ return S_OK; }

    ULONG STDMETHODCALLTYPE AddRef()
    {
        return InterlockedIncrement(&_cRef);
    }

    ULONG STDMETHODCALLTYPE Release()
    {
        ULONG ulRef = InterlockedDecrement(&_cRef);
        if (0 == ulRef)
        {
            delete this;
        }
        return ulRef;

    }

    HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, VOID **ppvInterface)
    {
        if (IID_IUnknown == riid)
        {
            AddRef();
            *ppvInterface = (IUnknown*)this;
        }
        else if (__uuidof(IAudioSessionEvents) == riid)
        {
            AddRef();
            *ppvInterface = (IAudioSessionEvents*)this;
        }
        else
        {
            *ppvInterface = NULL;
            return E_NOINTERFACE;
        }
        return S_OK;
    }
};

对应的.cpp:

HRESULT STDMETHODCALLTYPE AudioEndpointVolumeNotifierImpl::OnSimpleVolumeChanged(float NewVolume, BOOL NewMute, LPCGUID EventContext)
{
    PostStatusChange(NewVolume);

    return S_OK;
}

在以下代码的IClassFactory实例中失败:

...
AudioEndpointVolumeNotifierImpl* pObject = new AudioEndpointVolumeNotifierImpl();
    if (pObject == NULL)
    {
        return E_OUTOFMEMORY ;
    }
...

这段代码的很大一部分来自一些教程(特别是IUnknown的东西)。我不希望这段代码能够正常工作,但我不明白为什么它不能编译。

感谢。

3 个答案:

答案 0 :(得分:8)

奇怪的是,尽管此处OnIconPathChanged被描述为采用LPWCHAR参数:

http://msdn.microsoft.com/en-us/library/dd370939(VS.85).aspx

此处示例中显示LPCWSTR

http://msdn.microsoft.com/en-us/library/dd370797(VS.85).aspx

其中一个可能是错的;如果我们假设它是前者,并且该方法实际上采用LPCWSTR(无论如何在上下文中更有意义),这将解释您的错误。我会尝试将您的声明更改为

HRESULT STDMETHODCALLTYPE OnIconPathChanged(LPCWSTR NewIconPath, LPCGUID EventContext){return S_OK;}

答案 1 :(得分:7)

除了Eric Melski的回答(因为你说你是初学者,我认为他的答案对你来说不太清楚):

您收到此错误的原因是因为AudioEndpointVolumeNotifierImpl是一个抽象类,这意味着它具有纯虚方法,可以直接在类中定义,也可以从基类继承。

在你的情况下,显然是后者。

您要做的是实现您尝试过的继承纯虚方法,但如果方法的签名不相同,您只需定义一个重载,并保持基本纯虚方法不变。你的班级仍然是抽象的。因此错误信息。

答案 2 :(得分:2)

当您收到此错误时,您通常可以在输出控制台(即错误列表)中查找“由于以下成员:”并且您将看到使该类抽象的内容。