I've coded a small resource manager for my current project, and I've tried to learn how to use the boost smart pointers to avoid new/delete issues. However, I am not sure if my implementation is the best or if I am misusing the purpose of the smart pointers in some way. I would really like some feedback on the matter and yes, I did search the internet for similar stuff as well as the forums here, and although I did learn some things, none of them covered this particular case. Also, bear in mind that this implementation works and should be derived from by stuff like ImageManagers or FontManagers etc.
I used the boost::shared_ptr for the actual resource because of the reference counting (being able to see how many things are using the resource), but return a ResourcePtr (boost::weak_ptr in disguise) to avoid cyclic referencing (not sure if it will become a problem though). Maybe I should just return a boost::shared_ptr instead since I still need to convert the weak_ptr to a strong pointer to dereference it and use the resource it stores. I am not entirely sure. Please tell me if I forgot to include other info you might need
#ifndef RESOURCE_MANAGER_HPP
#define RESOURCE_MANAGER_HPP
#include <map>
#include <string>
#include <iostream>
#include <stdexcept>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/weak_ptr.hpp>
template<typename T>
class ResourceManager {
// Type definitions
protected:
typedef boost::shared_ptr<T> Resource;
public:
typedef boost::weak_ptr<T> ResourcePtr;
typedef std::map<std::string, Resource> ResourceMap;
public:
ResourceManager() {
resources.clear();
}
virtual ~ResourceManager() {
std::cout << "A ResourceManager is about to release " << AllocatedResources() << " resources" << std::endl;
};
ResourcePtr Request(const std::string& key) {
if (resources.find(key) == resources.end()) {
std::cerr << "Error: Requested resource with name " << key << " does not exist\n";
return ResourcePtr();
}
return ResourcePtr(resources[key]);
}
int AllocatedResources() {
return resources.size();
}
void PrintUsage() {
for (typename ResourceMap::iterator it = resources.begin(); it != resources.end(); ++it) {
std::cout << it->first << ": " << it->second.use_count() << std::endl;
}
}
protected:
ResourceMap resources;
};
// Runtime exception
class ResourceLoadingException : public std::runtime_error {
ResourceLoadingException(const std::string& message) : std::runtime_error(message) {}
};
#endif