2017-10-11 130 views
1

晚上好,指向對象的指針數組返回jibberish

我的任務是創建一個可以容納遊戲中所有對象的數組。 不幸的是,所有這些對象都是在不同的地方創建的 - 將它們手動放入一個數組中會很乏味 - 事實上,如果它們在創建它們的地方,我會感覺更好,但是對它們的引用存儲在一個數組..指針形式的引用。

所以,這就是我想通了,到目前爲止,我已經做了這麼指向對象的每個實例都加入到在構造函數中的數組,如下所示:

const int GAME_MAX_ENTS = 65536; 
class Object 
{ 
    public: 
     static Object* list[GAME_MAX_ENTS]; 
     char type[64] = "ENT_OBJECT"; 
     Object(); 
     ~Object(); 
}; 

Object::Object() 
{ 
    for (int i = 0; i < GAME_MAX_ENTS; i++) 
    { 
     if (!list[i]) 
     { 
      list[i] = this; 
      break; 
     } 
    } 
} 

Object* Object::list[GAME_MAX_ENTS]; 

現在,我的問題是, - 當我試圖查看該列表並在與創建對象不同的範圍中顯示'type'的值時,它會彈出廢話 - 我假設它是隨機存儲器輸出。

下面是我的部分試圖彈出正確的信息:

static void OnRender() 
{ 
    //Grid 
    SDL_RenderClear(renderer); 

    //Draw objects 
    for (int i = 0; i < GAME_MAX_ENTS; i++) 
    { 
     if (Object::list[i]) 
     { 
      Object* obj = Object::list[i]; 
      printf("%s\n", obj->type); 
     } 
    } 

    [...] 

..並讓一切​​儘可能明確,這裏就是我創建的對象的部分 - 提個醒,瓷磚就是一個類繼承從對象:

static void Initialize() 
    { 
     [...] 

     Tile tile; 
     Object obj; 
    } 

我相當肯定這一切都因爲我沒有與C++的經驗,我只是一個Web開發/ C#擦洗 - 不要去硬對我^^

+6

'Object obj;'是'Initialize'的本地對象。即使它將自己註冊到指針數組中,它仍然會在函數結束時超出範圍。 –

+2

這將是值得添加一個析構函數''對象'從數組中刪除'this' –

+2

C++的標準建議是使用'std :: vector'而不是數組。然後,您只需'push_back'新項目,而無需設置最大大小或掃描空閒插槽。 –

回答

3

它看起來像是在Initialize()中創建對象,然後超出範圍。在C++中,你必須管理自己的內存(當使用指針時)。存儲指向對象的指針並不妨礙它被銷燬。

您將需要存儲對象的副本,或者使用new顯式創建對象,然後管理指針(或使用C++智能指針來幫助您管理它們)。

+0

這似乎是我正在尋找的答案。 '新'關鍵字是否阻止析構函數自行運行? 我認爲這是由於垃圾收集? – Netheous

+0

替換我創建元素的方式:'''\t \t Tile * tile1 = new Tile(); \t \t \t Object * obj1 = new Object();'''工作! – Netheous

+1

@ Netheous是的。如果使用'new'創建一個對象,則必須使用'delete'手動刪除它。通常人們使用'std :: unique_ptr'來自動刪除它。 – Galik

0

您應該保持指向這些對象的指針,以便它們在構建時自動添加並在銷燬時自動刪除。這樣做的一個方法是讓觀察指針的set

// file object.h 
namespace game { 
    struct object // all game objects are derived from this 
    { 
    static set<const object*> const&list(); // return list of all objects 
    virtual draw() const;     // example of virtual function 
    object();        // only ctor: add this to list 
    object(object const&) = delete;   // disable copy ctor of base 
    virtual ~object();      // dtor: remove this from list 
    }; 
} 

// file object.cc 
#include "object.h" 
#include <set> 
#include <mutex> 
namespace { 
    std::mutex protect_object_list; 
    std::set<const object*> object_list; 
} 

std::set<const object*> const& object::list() 
{ 
    return object_list; 
} 

object::object() 
{ 
    std::lock_guard<std::mutex> lock(protect_object_list); 
    object_list.insert(this); 
} 

object::~object() 
{ 
    std::lock_guard<std::mutex> lock(protect_object_list); 
    object_list.erase(this); 
} 

使用可能看起來像

#include "object.h" 
namespace game { 
    struct tile : object 
    { 
    void draw() const override; 
    tile(position const&pos) : object() { /* ... */ } 
    tile(tile const&t) : object() { /* ... */ } 
    }; 

    void draw_objects() 
    { 
    for(auto const&obj:object::list()) 
     obj.draw(); 
    } 
} 

這樣,在object::list的對象由指針比較有序。如果您想要另外訂購,您可能需要使用std::map<size_t,const object*>,並將其用作構建對象時遞增的靜態計數器的關鍵字。