windows 初学C++问题;无法实例化抽象类(VS 中的 C2259)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/695346/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Beginning C++ problem; cannot instantiate abstract class (C2259 in VS)
提问by Kevin Montrose
I'm attempting to create a concrete instance of the IAudioEvents COM interface (available in Vista and later). This is my first foray into COM programming, so I'm probably just doing something stupid here. Anyway, the following code fails to compile with "C2259: 'AudioEndpointVolumeNotifierImpl' : cannot instantiate abstract class".
我正在尝试创建 IAudioEvents COM 接口的具体实例(在 Vista 及更高版本中可用)。这是我第一次涉足 COM 编程,所以我可能只是在这里做了一些愚蠢的事情。无论如何,以下代码无法使用“C2259:'AudioEndpointVolumeNotifierImpl':无法实例化抽象类”进行编译。
Class Definiton (AudioEndpointVolumeNotifierImpl.h):
类定义(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;
}
};
Corresponding .cpp:
对应的.cpp:
HRESULT STDMETHODCALLTYPE AudioEndpointVolumeNotifierImpl::OnSimpleVolumeChanged(float NewVolume, BOOL NewMute, LPCGUID EventContext)
{
PostStatusChange(NewVolume);
return S_OK;
}
Fails in an IClassFactory instance on the following code:
在以下代码的 IClassFactory 实例中失败:
...
AudioEndpointVolumeNotifierImpl* pObject = new AudioEndpointVolumeNotifierImpl();
if (pObject == NULL)
{
return E_OUTOFMEMORY ;
}
...
A good portion of this code IS lifted from some tutorials (the IUnknown stuff in particular). I'm not expecting this code to work just yet, but I can't see why it doesn't compile.
这段代码的很大一部分来自一些教程(特别是 IUnknown 的东西)。我不指望这段代码能正常工作,但我不明白为什么它不能编译。
Thanks.
谢谢。
回答by Eric Melski
Oddly, although OnIconPathChanged
is described as taking an LPWCHAR
parameter here:
奇怪的是,虽然这里OnIconPathChanged
被描述为带LPWCHAR
参数:
http://msdn.microsoft.com/en-us/library/dd370939(VS.85).aspx
http://msdn.microsoft.com/en-us/library/dd370939(VS.85).aspx
It is shown taking an LPCWSTR
in the example here:
它显示LPCWSTR
在此处的示例中:
http://msdn.microsoft.com/en-us/library/dd370797(VS.85).aspx
http://msdn.microsoft.com/en-us/library/dd370797(VS.85).aspx
One of these is probably wrong; if we assume it is the former, and that the method actually takes an LPCWSTR
(which makes more sense given the context anyway), that would explain your error. I would try changing your declaration to
其中之一可能是错误的;如果我们假设它是前者,并且该方法实际上采用了一个LPCWSTR
(无论如何考虑到上下文更有意义),那将解释您的错误。我会尝试将您的声明更改为
HRESULT STDMETHODCALLTYPE OnIconPathChanged(LPCWSTR NewIconPath, LPCGUID EventContext){return S_OK;}
回答by Beno?t
In addition to Eric Melski's answer (since you said you were a beginner, i assumed his answer would not be clear to you):
除了 Eric Melski 的回答(因为你说你是初学者,我认为他的回答对你来说不是很清楚):
The reason why you get this error is because AudioEndpointVolumeNotifierImpl is an abstract class, which means that it has pure virtual methods, either directly defined in the class, or inherited from base class.
之所以出现这个错误,是因为AudioEndpointVolumeNotifierImpl是一个抽象类,也就是说它有纯虚方法,要么直接在类中定义,要么继承自基类。
In your case, it's clearly the latter.
在你的情况下,显然是后者。
What you want to do is implement inherited pure virtual methods, which you have tried to do, but if the signature of the methods are not the same, you are simply defining an overload, and leaving the base pure virtual method unchanged. And your class is still abstract. Hence the error message.
您想要做的是实现继承的纯虚方法,您已经尝试过这样做,但是如果方法的签名不相同,那么您只是定义了一个重载,而基本纯虚方法保持不变。你的类仍然是抽象的。因此出现错误消息。
回答by jontejj
When you get this error you can often look in the output console (i.e not the error list) for "due to following members:" and you'll see what it is that makes the class abstract.
当您收到此错误时,您通常可以在输出控制台(即不是错误列表)中查看“由于以下成员:”,您将看到是什么使类变得抽象。