2016-02-14 88 views
0

我試圖創建一個基類(實體)的unique_ptr映射,其中只存儲唯一標識以標識我的對象。現在我想要創建不同的派生類(如玩家,平鋪等),它們應該從基類派生出來以獲得唯一的標識。獲取基類的指針以使用派生類的函數

如何將unique_ptr的內存位置作爲返回值傳遞,而不將其從我的地圖中移出?我的想法是在派生類傳入我的地圖時,使用基類的內存位置來訪問派生函數。

P.S. I'm目前正在對我自己的遊戲引擎(還是有點新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; 
} 
+0

您可以使用'std :: unique_ptr :: get'來檢索原始封裝指針。這是你要求的嗎? – paddy

+0

你應該創建一個SSCCE來描述你想要做什麼,因爲它很不清楚。你是否試圖傳遞'unique_ptr'給其他人填充?或者你是否試圖繞過它所包含的價值而不傳遞所有權?如果是後者,也許你想'shared_ptr'。 – kfsone

+0

我只是想獲得原始指針並希望能夠使用此原始指針訪問派生類的函數。 @paddy,是啊...試圖使用get()之前,但遺憾地忘記返回類型的實體*而不是std :: unique_ptr thy – cFx

回答

1

根本無法通過值返回unique_ptr而不移動它。

你可以做什麼卻是這些東西:

返回原始指針:

Entity* EntityManager::getEntity(int entityId) 
{ 
    return it->second.get(); 
} 

返回一個參考的unique_ptr:

std::unique_ptr<Entity>& EntityManager::getEntity(int entityId) 
{ 
    return it->second; 
} 

「問題」 與通過引用返回的是你總是需要返回一個對象的有效引用。在過去,我使用創建例如static std::unique_ptr<Entity> EmptyEntity對象的策略,如果getEntity在地圖中找不到,則getEntity將返回它。

例如:

static std::unique_ptr<Entity> EmptyEntity; 

std::unique_ptr<Entity>& EntityManager::getEntity(int entityId) 
{ 
    if (it == container.end()) 
     return EmptyEntity; 

    return it->second; 
} 

另一種解決方案將返回unique_ptr的指針,並返回nullptr,如果它不能找到任何實體。如果你想這樣做,使用Entity* EntityManager::getEntity()代替它會更容易。

+0

謝謝你的回答,目前嘗試=) – cFx

+0

工程就像一個魅力。 .. 再次感謝你!但是,當使用std :: unique_ptr &原始實體指針時,實際上我的好處是什麼?在轉換爲派生類時,很容易將Entity *轉換爲我的派生類......但是將unique_ptr轉換爲派生類時出現問題。 – cFx

+0

我會說沒有。在一天結束時,在兩種情況下,您需要確保指針在使用前不爲nullptr。唯一必須返回unique_ptr引用的情況是,如果您要修改它(有時需要)。 – Jts

相關問題