NordCoder Newbie Poster

Hi Daniweb,

I've been programming a base class resource manager for a game I'm working on, and so read up on boost's shared_ptr and weak_ptr. I'm done with it and it works and I would really appreciate some feedback on my choice of implementation and design. Am I using the smart pointers in a correct way? Am I overcomplicating things? etc...

Here's the 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; // Not to be used by users

    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; // Debug statement
		};

		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(); // "Empty" smart pointer, should throw exception instead in the future though
                    }

                    return ResourcePtr(resources[key]);
		}

		int AllocatedResources() {
                    return resources.size();
		}

	protected:
		ResourceMap resources;
};

// Runtime exception
class ResourceLoadingException : public std::runtime_error {
    ResourceLoadingException(const std::string& message) : std::runtime_error(message) {}
};

#endif

As you can see I am using the shared_ptr for the actual resource, but a weak_ptr as the return value for the Request member function to avoid cyclic references. I really don't expect cyclic references but I thought it might be a good idea to do anyways :) Note also that to use a requested resource, I have to turn the weak_ptr into a shared_ptr and use its dereference operator:

*myResourcePointer.lock()

. Also, derived classes (e.g. an ImageManager) need to implement their own Register/Load member function.