2012-04-16 127 views
0

所以即时通过我的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

即时通讯漂亮noob在这一切,所以感谢让我知道生病尽我所能。 – 2012-04-16 12:01:23

回答

0

好吧,这是我的想法后,看看代码和错误消息。

你不能像这样的函数返回图像和声音。他们是个人类型。你必须指定要返回的类型。当你将if/else放在模板中时,它仍然会检查它是否可以返回所有这些类型,并且会失败。

您必须返回Image和Sound继承的BaseClass *(或任何您想要调用它的)。

+0

噢谢谢男人我明白,我必须为此做一些polyphormic。非常感谢! – 2012-04-16 12:10:44

+0

-1,错误。你不能从一个函数返回'Image'和'Sound',这是真的,但是'Get '和'Get '是两个函数,所以这个答案背后的逻辑是有缺陷的,真正的问题是'Get '可以'不会返回'Sound',反之亦然,这不是一个大问题,你可以通过选择'Container'来选择合适的'Container'来解决这个问题,这是一个编译时的选择,因此不需要多态。 – MSalters 2012-04-16 15:00:32

+0

@MSalters不,我相信你是错的,请再次查看代码,根据代码,图像和声音从这个函数返回,并且不起作用,因为它在同一个函数中。 e在同一模板函数中迭代所有声音和图像。该函数只能返回一个类型,但它会尝试返回两个类型。这就是它失败的原因。 – mantler 2012-04-16 18:32:02

0

的模板功能已为编译器完全定义为能够使用它们。这意味着你必须将这些函数的主体从源文件移动到头文件。

编辑:

你必须检查你如何使用模板类。例如参见此错误消息:

ResourceManager.cpp:50:15: error: cannot convert ‘sz::SoundBuffer*’ to ‘sz::Image*’ in return

除非sz::SoundBuffer继承sz::Image你有类型之间的不匹配。

+0

对不起人没有工作,我把所有的代码移动到头文件,但错误似乎仍然出现:( – 2012-04-16 12:01:49

0

“编译时如果”通过模板部分专业化完成。但在这里它甚至不需要:

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; 
} 
+0

以及我不知道这是可能的,但谢谢你队友我一定会尝试一下! – 2012-04-17 15:37:33