0

这是我的代码(简化):

//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\...\documents\visual studio 2008\projects\core\fscore.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() 有两个定义:一个接受 a'const char *'作为参数 1,另一个接受'source *'作为参数 1。Intellisense 指出了这两个定义,但我无法让 VC++ 2008 express 编译器识别我想要的版本。我要改变什么?

4

1 回答 1

0

您的代码有两个问题,都在注释中确定。

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

调用者传递 a D3DXVECTOR3,但被调用者期望 a vec3df。这些是不同的类型,它们之间没有隐式转换,所以编译器会给你一些错误。在这种情况下,它给您的特定错误可能会有点误导。

(这两个类的大小相同并且具有相同的数据成员以相同的顺序并不重要。C++仅将两个类型视为相等,如果它们相等则不管它们如何在内部实现。

#2,来自@Named:

即使D3DXVECTOR3andvec3df是完全相同类型的 typedef,你还有另一个问题。您的两个虚拟方法具有相同的名称,因此它们是重载;由于函数重载与虚拟重载的交互方式类的重载实际上隐藏了父类的版本。例子:

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

Base::foo当我们foo在涉及的上下文中查找时,这会重新添加到候选列表中Derived。但是,更好的解决方案是使用唯一标识符来实现唯一功能:

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++ 中的函数重载是一种旨在解决非常具体问题的工具。如果您没有这个问题,请不要使用该工具!

于 2013-11-10T04:48:48.857 回答