所以我的ResourceManager类对于使用c ++的游戏有点问题。 所以我试图从我的常规addImage函数中创建一个模板函数,所以它也会添加声音,但我得到了一些我无法真正处理的错误你们可以帮帮我吗? :d
.HPP
#ifndef RESOURCE_MANAGER_HPP
#define RESOURCE_MANAGER_HPP
#include "Image.cpp"
#include "SoundBuffer.cpp"
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
typedef std::map<std::string, sz::Image*> ImagesContainer;
typedef std::map<std::string, sz::Image*>::iterator ImagesContainerIt;
typedef std::map<std::string, sz::SoundBuffer*> SoundsContainer;
typedef std::map<std::string, sz::SoundBuffer*>::iterator SoundsContainerIt;
typedef std::map<std::string, sf::Music*> MusicContainer;
typedef std::map<std::string, sf::Music*>::iterator MusicContainerIt;
namespace sz
{
// meanwhile this class is only for images, need to edit later for
// it to be also able to load sounds, etc...
class ResourceManager{
private:
ResourceManager() {};
ResourceManager(ResourceManager const&) {};
static ResourceManager *rm;
// add functions and variables here
ImagesContainer imagesContainer;
SoundsContainer soundsContainer;
MusicContainer musicContainer;
template <class type>
void AddNew(std::string imagePath);
public:
static ResourceManager *Instance();
// add functions here
template <class type>
type *Get(std::string imagePath);
};
}
#endif
的.cpp
#include "ResourceManager.hpp"
#include <typeinfo>
namespace sz
{
ResourceManager *ResourceManager::rm = NULL;
ResourceManager *ResourceManager::Instance()
{
if (!rm)
rm = new ResourceManager;
return rm;
}
template <class type>
void ResourceManager::AddNew(std::string filePath)
{
type *item = new type(filePath);
if(typeid(type) == typeid(sz::Image))
imagesContainer[filePath] = item;
else if(typeid(type) == typeid(sz::SoundBuffer))
soundsContainer[filePath] = item;
else
return;
}
template <class type>
type *ResourceManager::Get(std::string filePath)
{
if(typeid(type) == typeid(sz::Image))
{
ImagesContainerIt it = imagesContainer.find(filePath);
if(it == imagesContainer.end())
{
AddNew<type>(filePath);
}
it = imagesContainer.find(filePath);
return it->second;
}
else if(typeid(type) == typeid(sz::SoundBuffer))
{
SoundsContainerIt it = soundsContainer.find(filePath);
if(it == soundsContainer.end())
{
AddNew<type>(filePath);
}
it = soundsContainer.find(filePath);
return it->second;
}
else
return NULL;
}
}
错误@ _ @
g++ -Wall -c "Sprite.cpp" (in directory: /home/gannash/Desktop/Open Heroes/Engine)
In file included from Sprite.cpp:2:0:
ResourceManager.cpp: In member function ‘type* sz::ResourceManager::Get(std::string) [with type = sz::Image, std::string = std::basic_string<char>]’:
Sprite.cpp:10:65: instantiated from here
ResourceManager.cpp:50:15: error: cannot convert ‘sz::SoundBuffer*’ to ‘sz::Image*’ in return
ResourceManager.cpp: In member function ‘void sz::ResourceManager::AddNew(std::string) [with type = sz::Image, std::string = std::basic_string<char>]’:
ResourceManager.cpp:36:5: instantiated from ‘type* sz::ResourceManager::Get(std::string) [with type = sz::Image, std::string = std::basic_string<char>]’
Sprite.cpp:10:65: instantiated from here
ResourceManager.cpp:23:4: error: cannot convert ‘sz::Image*’ to ‘std::map<std::basic_string<char>, sz::SoundBuffer*>::mapped_type {aka sz::SoundBuffer*}’ in assignment
ResourceManager.cpp: In member function ‘type* sz::ResourceManager::Get(std::string) [with type = sz::Image, std::string = std::basic_string<char>]’:
ResourceManager.cpp:55:2: warning: control reaches end of non-void function [-Wreturn-type]
Compilation failed.
答案 0 :(得分:0)
必须完全定义模板化函数,编译器才能使用它们。这意味着您必须将这些函数的主体从源文件移动到头文件。
修改强>
您必须检查模板类的使用方式。请参阅此错误消息:
ResourceManager.cpp:50:15:错误:无法将'sz :: SoundBuffer *'转换为'sz :: Image *'作为回报
除非sz::SoundBuffer
继承自sz::Image
,否则您的类型之间会不匹配。
答案 1 :(得分:0)
好的,看看代码和错误消息后,这是我的想法。
您无法从相同的功能返回图像和声音。它们是个人类型。您必须指定要返回的类型。当您将if / else放入模板时,它仍然会检查它是否可以返回所有这些类型,并且会失败。
你必须返回Image和Sound继承的BaseClass *(或任何你想要的名字)。
答案 2 :(得分:0)
“编译时间if”是通过模板部分特化完成的。但这里甚至不需要它:
template<typename type> struct Container {
static std::map<std::string, type*> container;
};
std::map<std::string, sz::Image*>& ImagesContainer = Container<sz::Image>::container;
// etc...
template <class type>
void ResourceManager::AddNew(std::string filePath)
{
type *item = new type(filePath);
Container<type>::container[filePath] = item;
}