Proper use of boost smart pointers for a resource manager

Started by
2 comments, last by NordCoder 12 years, 10 months ago
Hi all!

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
Advertisement
Aren't you doing it backwards? You don't want the app to lose the pointer to the object if the manager dies, you want the manager to lose the pointer to the object if the app isn't using it anymore...
Regarding the use of weak_ptr, is there a particular case you have in mind where you expect cyclic references to occur?
@Telastyn[color="#1c2837"]: So what you mean is that I should load resources as I do now, but if a resource's use_count() becomes zero (no objects are referencing it anymore) I should remove it from the manager? Wouldn't I need to reload resources multiple times in that scenario or did I misunderstand you?
[color="#1c2837"]

[color="#1c2837"]@jyk: Since the actual boost::shared_ptr resource is hidden from the user and there is no direct access, I can't really think of a smart pointer pointing back to a resource. Neither can I think of a game-related situation where this would occur. So no.

This topic is closed to new replies.

Advertisement