我正在爲一個項目設計和實體組件系統,而C++內存管理給了我幾個問題。我只是想確保我的設計是合法的。Unique_ptr編譯器錯誤
所以開始我有存儲組件的載體的實體類:
class Entity
{
private:
std::vector<std::unique_ptr<Component> > components;
public:
Entity() { };
void AddComponent(Component* component)
{
this -> components.push_back(std::unique_ptr<Component>(component));
}
~Entity();
};
哪,如果我沒有記錯的話意味着,當調用析構函數(即使是默認的,編譯器創建一個),該析構函數將調用〜組件,它將爲vector中的每個元素調用〜std :: unique_ptr,並導致每個Component的銷燬,這正是我想要的。
組件類有虛擬方法,但重要的部分是它的構造:
Component::Component(Entity parent)
{
parent.addComponent(this) // I am not sure if this would work like I expect
// Other things here
}
只要通過this
的方法工作,這也是我想要做什麼。我的困惑在於工廠。我想要做的是沿着線的東西:
std::shared_ptr<Entity> createEntity()
{
std::shared_ptr<Entity> entityPtr(new Entity());
new Component(*parent);
// Initialize more, and other types of Components
return entityPtr;
}
現在,我認爲,這種設置會離開組件的所有權在其父實體,這正是我想要的手中。首先是一個小問題,我是否需要通過引用或指針或其他東西將實體傳遞給Component構造函數?如果我理解C++,它會通過值傳遞,這意味着它被複制,並且複製的實體會死在構造函數的末尾。
第二,主要問題是基於此示例的代碼不會編譯。完整的錯誤太大,無法打印,但我想我知道發生了什麼。編譯器的錯誤說我不能刪除一個不完整的類型。我的組件類有一個純粹的虛擬析構函數,執行如下:
inline Component::~Component() { };
在頭部的末尾。但是,由於整個觀點是Component實際上是一個接口。我從here知道unique_ptr銷燬需要一個完整的類型。問題是,我該如何解決這個問題?作爲參考,我使用的是gcc 4.4.6。
好的,那就是我的想法。謝謝。 –
更改簽名不會解決OP的問題。他們將'this'的所有權傳遞給'unique_ptr'。 – jrok
@jrok:請詳述一下嗎?是的,Component只是用新的方式創建的,並且隱含地將其所有權傳遞給「父」實體。哪個問題沒有解決? (我假設最後一塊意味着* entityPtr真的是參數) –