I recently started using the template-features of C++. Unfortunately, I think I did not quite understand how to write the implementation of a templated class. I got one templated class with implementation, and one templated class with a subclass that has an implementation. The compiler gives me those 2019 Linker errors on nearly all methods of both classes - And I'm pretty sure the problem lies in the way I implemented the templated classes. When I looked up those errors, most of the time it occured when someone forgot to implement a method he had defined in the header, but I'm pretty sure that this is not the case here.
My code looks as follows:
//ResourceManager.h
#ifndef ResMan_H
#define ResMan_H
#include "Loader.h"
#include <iostream>
#include <map>
#include <string>
template<class Res>
class ResourceManager {
private:
std::map<int, Res*> resourceList;
Loader<Res> * loader;
public:
~ResourceManager();
ResourceManager(Loader<Res> * loader);
void load(int key, std::string filePath);
Res* request(int key);
void unload(int key);
void dispose();
};
#endif
Implementation:
//ResourceManager.cpp
#include "ResourceManager.h"
#include <assert.h>
template<class Res>
ResourceManager<Res>::~ResourceManager(){
this->dispose();
}
ResourceManager<class Res>::ResourceManager(Loader<Res> * loader){
this->loader = loader;
}
void ResourceManager<class Res>::load(int key, std::string filePath){
unload(key);
this->resourceList[key] = this->loader->loadFromFile(filePath);
}
Res* ResourceManager<class Res>::request(int key){
assert(this->resourceList.find(key) == this->resourceList.end() && "Resource could not be found. Make sure to load it before requesting it.");
return this->resourceList[key];
}
template<class Res>
void ResourceManager<Res>::unload(int key){
if (this->resourceList.find(key) != this->resourceList.end()){
delete this->resourceList[key];
this->resourceList.erase(key);
}
}
void ResourceManager<class Res>::dispose(){
for(std::pair<int, Res*> kv : resourceList){
delete kv.second;
}
resourceList.clear();
}
Loader.h
#ifndef Loader_H
#define Loader_H
#include <iostream>
template<class Res>
class Loader {
public:
virtual Res* loadFromFile(std::string filePath);
};
#endif
TextureLoader.h
#ifndef TextureLoader_H
#define TextureLoader_H
#include "Loader.h"
#include <SFML\Graphics.hpp>
class TextureLoader : public Loader<sf::Texture> {
public:
sf::Texture* loadFromFile(std::string path);
};
#endif
Implementation
#include "TextureLoader.h"
sf::Texture* TextureLoader::loadFromFile(std::string path){
sf::Texture* texture = new sf::Texture();
texture->loadFromFile(path);
std::cout << "Texture loaded" << std::endl;
return texture;
}
Sorry for the long code, but even if the body of those functions should be irrelevant I rather post it since I'm not 100% that the error doesnt lie in that code.