获取 base-class 的指针以使用派生 class 的函数
Get pointer of base-class to use functions of derived class
我正在尝试创建基础 class(实体)的 unique_ptr 地图,其中仅存储唯一 ID 以标识我的对象。现在我想创建不同的派生 classes(如播放器、tile 等),它们应该派生自 base-class 以具有唯一标识。
如何将 unique_ptr 的内存位置作为 return 值传递而不将其移出我的地图?我的想法是在将派生的 classes 传递到我的映射时,使用基 class 的内存位置来访问派生函数。
P.S。我目前正在开发自己的游戏引擎(对 cpp 还是有点陌生)
这是我当前的 EntityManager WIP:
EntityManager.hpp
#pragma once
#include "TSingleton.hpp"
#include "Entity.hpp"
#include <map>
#include <iostream>
#include <memory>
#define g_pEntityManager EntityManager::Get()
class EntityManager : public TSingleton<EntityManager>
{
public:
EntityManager();
~EntityManager();
// add entity to entity-manager and returns id in entityManager
int addEntity(std::unique_ptr<Entity> gameObject);
// get pointer to entityManager
std::map<int, std::unique_ptr<Entity>> getEntityManager() { return m_EntityManager; };
// destroy entity
void killEntity(int entityId);
// get entity
std::unique_ptr<Entity> getEntity(int entityId);
private:
int m_nEntityCounter = 0;
std::map<int, std::unique_ptr<Entity>> m_EntityManager;
};
EntityManager.cpp
EntityManager::EntityManager()
{
}
EntityManager::~EntityManager()
{
}
int EntityManager::addEntity(std::unique_ptr<Entity> gameObject)
{
int size = m_EntityManager.size();
gameObject->setID(size);
// add entity-object to EntityManager and increment entity_id;
m_EntityManager.insert(std::make_pair(size, std::move(gameObject)));
std::cout << "Entity added! " << m_EntityManager.size() << std::endl;
m_nEntityCounter ++;
return size;
}
void EntityManager::killEntity(int entityId)
{
std::map<int, std::unique_ptr<Entity>>::iterator it = m_EntityManager.find(entityId);
if (it != m_EntityManager.end())
{
m_EntityManager.erase(it);
}
else
std::cout << "Couldn`t kill Entity with id: " << entityId << " , because there is no Entity with this id in EntityManager" << std::endl;
}
std::unique_ptr<Entity> EntityManager::getEntity(int entityId)
{
std::map<int, std::unique_ptr<Entity>>::iterator it = m_EntityManager.find(entityId);
if (it != m_EntityManager.end())
{
if (it->second != nullptr)
{
std::unique_ptr<Entity>& found = it->second;
return std::move(found);
}
else
std::cout << "Pointer to object is NULL!" << std::endl;
}
else
std::cout << "Couldn`t find Entity with id: " << entityId << " in EntityManager" << std::endl;
}
根本不可能 return a unique_ptr 按值而不移动它。
然而,您可以做的是以下事情之一:
Return 原始指针:
Entity* EntityManager::getEntity(int entityId)
{
return it->second.get();
}
Return 引用 unique_ptr:
std::unique_ptr<Entity>& EntityManager::getEntity(int entityId)
{
return it->second;
}
"problem" 与 return 引用是您始终需要 return 对对象的有效引用。过去我使用过创建 static std::unique_ptr<Entity> EmptyEntity
对象的策略,如果在地图中找不到对象,getEntity 会 return 它。
例如:
static std::unique_ptr<Entity> EmptyEntity;
std::unique_ptr<Entity>& EntityManager::getEntity(int entityId)
{
if (it == container.end())
return EmptyEntity;
return it->second;
}
另一种解决方案是 return 通过指针访问 unique_ptr
,如果找不到任何实体,则 return nullptr
。如果你打算这样做,那么使用 Entity* EntityManager::getEntity()
会更容易。
我正在尝试创建基础 class(实体)的 unique_ptr 地图,其中仅存储唯一 ID 以标识我的对象。现在我想创建不同的派生 classes(如播放器、tile 等),它们应该派生自 base-class 以具有唯一标识。
如何将 unique_ptr 的内存位置作为 return 值传递而不将其移出我的地图?我的想法是在将派生的 classes 传递到我的映射时,使用基 class 的内存位置来访问派生函数。
P.S。我目前正在开发自己的游戏引擎(对 cpp 还是有点陌生)
这是我当前的 EntityManager WIP:
EntityManager.hpp
#pragma once
#include "TSingleton.hpp"
#include "Entity.hpp"
#include <map>
#include <iostream>
#include <memory>
#define g_pEntityManager EntityManager::Get()
class EntityManager : public TSingleton<EntityManager>
{
public:
EntityManager();
~EntityManager();
// add entity to entity-manager and returns id in entityManager
int addEntity(std::unique_ptr<Entity> gameObject);
// get pointer to entityManager
std::map<int, std::unique_ptr<Entity>> getEntityManager() { return m_EntityManager; };
// destroy entity
void killEntity(int entityId);
// get entity
std::unique_ptr<Entity> getEntity(int entityId);
private:
int m_nEntityCounter = 0;
std::map<int, std::unique_ptr<Entity>> m_EntityManager;
};
EntityManager.cpp
EntityManager::EntityManager()
{
}
EntityManager::~EntityManager()
{
}
int EntityManager::addEntity(std::unique_ptr<Entity> gameObject)
{
int size = m_EntityManager.size();
gameObject->setID(size);
// add entity-object to EntityManager and increment entity_id;
m_EntityManager.insert(std::make_pair(size, std::move(gameObject)));
std::cout << "Entity added! " << m_EntityManager.size() << std::endl;
m_nEntityCounter ++;
return size;
}
void EntityManager::killEntity(int entityId)
{
std::map<int, std::unique_ptr<Entity>>::iterator it = m_EntityManager.find(entityId);
if (it != m_EntityManager.end())
{
m_EntityManager.erase(it);
}
else
std::cout << "Couldn`t kill Entity with id: " << entityId << " , because there is no Entity with this id in EntityManager" << std::endl;
}
std::unique_ptr<Entity> EntityManager::getEntity(int entityId)
{
std::map<int, std::unique_ptr<Entity>>::iterator it = m_EntityManager.find(entityId);
if (it != m_EntityManager.end())
{
if (it->second != nullptr)
{
std::unique_ptr<Entity>& found = it->second;
return std::move(found);
}
else
std::cout << "Pointer to object is NULL!" << std::endl;
}
else
std::cout << "Couldn`t find Entity with id: " << entityId << " in EntityManager" << std::endl;
}
根本不可能 return a unique_ptr 按值而不移动它。
然而,您可以做的是以下事情之一:
Return 原始指针:
Entity* EntityManager::getEntity(int entityId)
{
return it->second.get();
}
Return 引用 unique_ptr:
std::unique_ptr<Entity>& EntityManager::getEntity(int entityId)
{
return it->second;
}
"problem" 与 return 引用是您始终需要 return 对对象的有效引用。过去我使用过创建 static std::unique_ptr<Entity> EmptyEntity
对象的策略,如果在地图中找不到对象,getEntity 会 return 它。
例如:
static std::unique_ptr<Entity> EmptyEntity;
std::unique_ptr<Entity>& EntityManager::getEntity(int entityId)
{
if (it == container.end())
return EmptyEntity;
return it->second;
}
另一种解决方案是 return 通过指针访问 unique_ptr
,如果找不到任何实体,则 return nullptr
。如果你打算这样做,那么使用 Entity* EntityManager::getEntity()
会更容易。