vc++编译器忽略重载函数
VC++ compiler ignores an overloaded function
下面是我的代码(简化):
//wrapper.h
#include <play3d.h>
class wrapper
{
private:
soundengine *soundEngine;
public:
sound *playSound3D(source *source, D3DXVECTOR3 pos, bool loop=false);
};
//wrapper.cpp
sound *wrapper::playSound3D(source *source, D3DXVECTOR3 pos, bool loop)
{
return soundEngine->play3D(source, pos, loop);
};
这里是我的完整代码(按要求)。它使用irrKlang声音引擎:
//irrKlang.h
virtual ISound* play3D(ISoundSource* source, vec3df pos,
bool playLooped = false,
bool startPaused = false,
bool track = false,
bool enableSoundEffects = false) = 0;//the version i want
virtual ISound* play3D(const char* soundFileName, vec3df pos,
bool playLooped = false,
bool startPaused = false,
bool track = false,
E_STREAM_MODE streamMode = ESM_AUTO_DETECT,
bool enableSoundEffects = false) = 0;//the version vc++ finds
//fsCore.h
#include <irrklang.h>
class fsEngine
{
private:
static fsEngine *instance;
static fsBool exists;
irrklang::ISoundEngine *soundEngine;
fsEngine();
~fsEngine();
public:
static fsEngine *getInstance()
{
if (!exists)
{
instance = new fsEngine();
exists = true;
return instance;
}
else
{
return instance;
}
};
void release()
{
exists = false;
delete instance;
soundEngine->drop();
};
public:
irrklang::ISoundSource *loadSound(fsString filename);
irrklang::ISoundSource *cloneSound(irrklang::ISoundSource *source, fsString alias=NULL);
irrklang::ISound *playSound2D(irrklang::ISoundSource *source, fsBool loop=false);
irrklang::ISound *playSound3D(irrklang::ISoundSource *source, D3DXVECTOR3 soundpos, fsBool loop=false);
};
//fsCore.cpp
#include "fsCore.h"
irrklang::ISound *fsEngine::playSound3D(irrklang::ISoundSource *source, D3DXVECTOR3 soundpos, bool loop)
{
return soundEngine->play3D(source, soundpos, loop);
};
我从哪里得到一个C2664错误。
1>c:users...documentsvisual studio 2008projectscorefscore.cpp(20) : error C2664: 'irrklang::ISound *irrklang::ISoundEngine::play3D(const char *,irrklang::vec3df,bool,bool,bool,irrklang::E_STREAM_MODE,bool)' : cannot convert parameter 1 from 'irrklang::ISoundSource *' to 'const char *'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Play3D()有两个定义:一个接受'const char *'
作为参数1,另一个接受'source *'
作为参数1。Intellisense指出了这两个定义,但我无法让vc++ 2008 express编译器识别我想要的版本。我要改变什么?
你的代码有两个问题,都在注释中指出了。
#1,来自@john:
virtual ISound* play3D(ISoundSource* source,
vec3df pos,
bool playLooped = false,
bool startPaused = false,
bool track = false,
bool enableSoundEffects = false) = 0;
irrklang::ISound *fsEngine::playSound3D(irrklang::ISoundSource *source,
D3DXVECTOR3 soundpos, bool loop)
{
return soundEngine->play3D(source, soundpos, loop);
}
呼叫方传递D3DXVECTOR3
,但被呼叫方期望传递vec3df
。它们是不同的类型,它们之间没有隐式转换,所以编译器会给你一些类型的错误。在这种情况下,它给你的特定错误可能有点误导。
(两个类的大小相同,数据成员的顺序相同,这并不重要。c++只在相等时才将两种类型视为相等,而不管它们是如何在内部实现的。)
#2, from @Named:
即使D3DXVECTOR3
和vec3df
是完全相同类型的类型定义,您也会遇到另一个问题。你的两个虚方法有相同的名字,所以它们是重载的;而且由于函数over-加载与虚over-加载的交互方式,子类的重载实际上隐藏了父类的版本。例子:
struct X; struct Base { virtual void foo(X *); };
struct Y; struct Derived : public Base { virtual void foo(Y *); };
void f(Derived *d, X *x) { d->foo(x); }
% clang++ -Wall test.cc
test.cc:2:59: warning: 'Derived::foo' hides overloaded virtual function [-Woverloaded-virtual]
struct Y; struct Derived : public Base { virtual void foo(Y *); };
^
test.cc:1:59: note: hidden overloaded virtual function 'Base::foo' declared here
struct X; struct Base { virtual void foo(X *); };
^
test.cc:4:39: error: cannot initialize a parameter of type 'Y *' with an lvalue of type 'X *'
void f(Derived *d, X *x) { d->foo(x); }
^
test.cc:2:66: note: passing argument to parameter here
struct Y; struct Derived : public Base { virtual void foo(Y *); };
^
解决这个问题的一个方法是使用using
指令:
struct X; struct Base { virtual void foo(X *); };
struct Y; struct Derived : public Base { virtual void foo(Y *); using Base::foo; };
void f(Derived *d, X *x) { d->foo(x); }
当我们在涉及Derived
的上下文中查找foo
时,这将Base::foo
重新添加到候选列表中。然而,一个更好的解决方案是为唯一的功能使用唯一标识符:
struct X; struct Base { virtual void foox(X *); };
struct Y; struct Derived : public Base { virtual void fooy(Y *); };
void f(Derived *d, X *x) { d->foox(x); }
这里没有你想调用哪个函数的混淆——没有编译器的混淆,和没有人类读者的混淆。c++中的函数重载是一种用来解决特定问题的工具。如果你没有这个问题,就不要使用这个工具!
相关文章:
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 可以打印矢量和矢量中的矢量的非重载C++函数
- 错误 没有与参数列表匹配的重载函数"getline"实例
- 使用模板重载函数
- C++线程中,没有重载函数接受 X 参数
- std::vector 没有重载函数的实例与参数列表匹配
- C++重载函数,一个采用基类的参数,另一个采用派生类的参数
- 错误:无法解析对重载函数的引用;你的意思是调用它吗?
- 对重载函数find_first_not_of的不明确调用
- 如何从重载解析中删除重载函数?
- CUDA:重载函数"isnan"的多个实例
- C++派生类重载函数(带有 std::function 参数)不可见
- 避免在人为的重载函数调用中拼写出类型
- C++:如何为多个重载函数保留通用代码路径?
- 什么时候可以使用常量装饰调用我的重载函数?
- 尝试使用谓词函数会导致错误:"std::sort"未找到匹配的重载函数
- std::调用,未找到匹配的重载函数
- 为什么在传递长整型时调用具有两个双精度类型的参数的重载函数?
- 为什么使用不匹配的参数调用重载函数仍然有效
- 如何通过签名作为模板参数来解决重载函数?