Following should work:
friend class ResourceManager;
should be in each derivated classes.
(friend is not inherited).
class ResourceManager;
/// abstract base class
class Identity
{
public:
int Id() const { return _id; }
/// make this an abstract class
virtual ~Identity() = 0;
// Forbid any copy
Identity(const Identity&) = delete;
Identity(const Identity&&) = delete;
Identity& operator = (const Identity&) = delete;
Identity& operator = (Identity&&) = delete;
protected:
Identity() { _id = _nextId++; }
private:
int _id;
static int _nextId;
};
// empty destructor
Identity::~Identity() {}
int Identity::_nextId = 0;
/// derived classes
class Component : public Identity
{
friend class ResourceManager;
public:
~Component() { }
protected:
Component() = default;
};
class Entity : public Identity
{
friend class ResourceManager;
public:
~Entity() { }
protected:
Entity() = default;
};
class ResourceManager
{
public:
template<typename T>
T& Create()
{
std::unique_ptr<T> ptr(new T);
T& res = *ptr;
_resources[ptr->Id()] = std::move(ptr);
return res;
}
/// TODO: need to make sure that resource ID is actually of type T
/// and that _resources contains ID.
template<typename T>
T* Get(int id)
{
auto it = _resources.find(id);
if (it == _resources.end()) {
return nullptr;
}
return dynamic_cast<T*>(it->second.get());
}
private:
std::map<int, std::unique_ptr<Identity>> _resources;
};
Note that since ResourceManager
owns the resource I change std::shared_ptr
to std::unique_ptr
.
I fixed ResourceManager::Get
with invalid id.