Sign in to follow this  
NordCoder

Proper use of boost smart pointers for a resource manager

Recommended Posts

NordCoder    121
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 :)

[code]
#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
[/code]

Share this post


Link to post
Share on other sites
Telastyn    3777
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...

Share this post


Link to post
Share on other sites
jyk    2094
Regarding the use of weak_ptr, is there a particular case you have in mind where you expect cyclic references to occur?

Share this post


Link to post
Share on other sites
NordCoder    121
@Telastyn[size="2"][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][/size]
[size="2"][color="#1c2837"]
[/color][/size]
[size="2"][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. [/color][/size]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this