2015-06-20 45 views
0

我遵循V. Romeo的實體管理教程(位於GitHub & Youtube)。(Dangling?)從函數返回的引用不「工作」

我又試圖改寫類CEntityCComponent和測試CPosition(主要來自內存羅密歐的視頻/代碼)。 我遇到的問題是,在我的主要我創建一個CEntity在堆棧&添加一個組件。當我通過addComponent()添加組件時,我抓住對新創建組件的引用,由addComponent()返回。

當我現在想通過返回的引用修改組件時,我所做的更改不會反映回實體(的組件)。看起來像一個懸而未決的參考,但我無法找到我犯的錯誤。

任何人都可以請指出我在做什麼錯在這裏?

Follwing我CEntity類:

#include <array> 
#include <bitset> 
#include <memory> 
#include <cassert> 
#include <stdexcept> 

namespace inc 
{ 

using ComponentID = unsigned int; 

ComponentID getNewID() 
{ 
    static ComponentID id = 0; 
    return id++; 
} 

template <typename T> 
ComponentID getComponentID() 
{ 
    static ComponentID component_id = getNewID(); 
    return component_id; 
} 

// Forward declarations used by CEntity: 
struct CComponent; 

class CEntity 
{ 
public: 
    static const ComponentID MAX_COMPONENTS = 30; 
    using ComponentArray     = std::array<std::unique_ptr<CComponent>, CEntity::MAX_COMPONENTS>; 
    using ComponentBitset     = std::bitset<MAX_COMPONENTS>; 

public: 
    CEntity() 
    { 
    } 

    ~CEntity() 
    { 
    } 

    template <typename T, typename... TArgs> 
    T& addComponent(TArgs&&... Args) 
    { 
     // Ensure that CComponent is base of T: 
     static_assert(std::is_base_of<CComponent, T>::value, "CEntity::addComponent(): Component has to be derived from CComponent."); 

     // Get id for component type 
     auto component_id = getComponentID<T>(); 
     assert(component_id <= MAX_COMPONENTS); 

     // Create component 
     auto component  = std::make_unique<T>(std::forward<TArgs>(Args)...); 
     auto component_ptr = component.get(); 

     // Initialize the component 
     component->entity = this; 
     component->init(); 

     // Store component 
     components_[component_id] = std::move(component); 

     // Set component flag 
     component_bitset_[component_id] = true; 

     return *component_ptr; 
    } 

private: 
    ComponentArray components_; 
    ComponentBitset component_bitset_; 
}; 

這裏我CComponent & CPosition類:

// Forward required by CComponent 
class CEntity; 

// Abstract base class for components 
struct CComponent 
{ 
    using TimeSlice = float; 

    // Pointer to parent entity 
    CEntity* entity; 

    virtual ~CComponent() {} 

    virtual void init() {} 
    virtual void update(const TimeSlice DT) {} 
    virtual void draw() const {} 
}; 

struct CPosition : public CComponent 
{ 
    sf::Vector2f position{0,0}; 
}; 

而且我主要功能:

#include "Entity.h" 
#include "ComponentCollection.h" 
int main() 
{ 
    inc::CEntity entity; 

    auto pos = entity.addComponent<inc::CPosition>(); 
    pos.position.x = 1; 
    return 0; 
} 
+1

在'的ComponentID getComponentID() { 靜態的ComponentID COMPONENT_ID = getNewID(); return component_id; }' 變量'component_id'在分配一次後永遠不會改變它的值,因爲它是靜態的。看起來不像你想要的那樣。 – SU3

+0

@ SU3這正是我想要的,否則我不會一遍又一遍地得到相同的ID(這正是我想要的)。這將爲我放置的每個T返回一個新ID。我希望每個T的編號都相同。 – Incubbus

+0

我明白了,這就是爲什麼您使用模板功能。 – SU3

回答

6

問題就在這裏:

auto pos = entity.addComponent<inc::CPosition>(); 
^^^^^ 

addComponent()返回一個參考,一切都在這個函數是罰款(沒有懸掛引用的問題,據我可以告訴)。但是auto不會推斷出一個引用類型,除非你告訴它 - 所以你只是在那裏做一個副本。該解決方案僅僅是告訴它推斷出的引用:

auto& pos = entity.addComponent<inc::CPosition>();