2012-04-16 4 views
0

그래서 저는 메신저를위한 ResourceManager 클래스에 약간의 문제가 있습니다. 그래서 나는 소리를 추가 할 수 있도록 템플릿 함수를 내 일반 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 

통화 당

#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

좋아,이 코드와 오류 메시지를 살펴본 후 내 생각입니다.

이미지와 사운드를 같은 기능으로 반환 할 수 없습니다. 그것들은 개별 유형입니다. 그리고 리턴 될 타입을 지정해야합니다. 템플릿에 if/else를 넣을 때 모든 유형을 반환 할 수 있는지 계속 확인하고 실패합니다.

이미지와 사운드가 상속하는 BaseClass * (또는 호출 할 내용)를 반환해야합니다.

+0

오, 고마워 남자 내가 뭔가 polyphormic 이걸 확인해야 이해합니다. 덕분에 대단히! –

+0

-1, 잘못되었습니다. 하나의 함수에서'Image'와'Sound'를 돌려 줄 수는 없지만'Get '와'Get '는 두 가지 함수이므로이 대답 뒤에있는 논리는 결함이 있습니다. 실제 문제는'Get ' 'Sound'를 반환하고 그 반대도 마찬가지입니다. 이것은 큰 문제는 아니며,'type'을 사용하여 올바른 'Container'를 선택하여 해결합니다. 이것은 다형성이 필요하지 않으므로 컴파일 타임 선택입니다. – MSalters

+0

@MSalters 당신이 틀렸다고 생각하지 않습니다. 코드를 다시보십시오. 코드에 따르면 이미지와 사운드가 모두이 함수에서 반환되며 동일한 함수이므로 작동하지 않습니다. 대구 e는 동일한 템플릿 함수에서 모든 사운드 및 이미지를 반복합니다. 이 함수는 하나의 유형 만 반환 할 수 있지만 둘 다 반환하려고합니다. 그것이 실패하는 이유입니다. – mantler

0

템플릿 기반 기능이 완전히 수에 컴파일러에 대해 정의 될 수있다 그것을 써. 즉, 그 함수의 본문을 소스 파일에서 헤더 파일로 이동해야합니다.

편집 :

당신은 확인해야 템플릿 클래스를 사용하는 방법. 예를 들어,이 오류 메시지를 참조하십시오

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

sz::SoundBuffer하지 않는 한 상속을 sz::Image에서 당신은 유형 간의 불일치가 있습니다.

+0

미안 남자 didnt 일, 헤더 파일에 모든 코드를 이동하지만 오류가 여전히 나타납니다. ( –

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

글쎄,이게 가능하다는 것을 몰랐지만, 네가 고맙다는 것을 확실히 이해할 것이다! –