2013-06-12 60 views
0

我正在開發一個遊戲,我有一個樹類。這個類有一個叫做「木」的int,它保留了樹中留下的木材數量。還有一個功能可以跟蹤所有事件。當值達到0我想刪除這個對象(順便說一句,我使用的代碼塊和SDL庫)刪除類中的成員函數中的對象

的handle_events功能:

void Tree::handle_events(SDL_Event event, int MouseX, int MouseY, int Xoffset, int Yoffset) { 
if(event.type == SDL_MOUSEBUTTONDOWN) { 
    if(event.button.button == SDL_BUTTON_LEFT) { 

     if((MouseX >= (xPos - Xoffset)) && (MouseX <= ((xPos + 50) - Xoffset)) && (MouseY >= (yPos - Yoffset)) && (MouseY <= ((yPos + 50) - Yoffset))) { 
      selected = true; 
     } else { 
      selected = false; 
     } 
    } 
} 

if(wood <= 0) { 
    delete this; 
} 

}

當我啓動遊戲和「木材」歸零,樹仍然在那裏工作。 請幫助

編輯:

while(SDL_PollEvent(&event)) { 
     MouseX = event.motion.x; 
     MouseY = event.motion.y; 

     menu_button.handle_button_events(event, MouseX, MouseY); 
     exit_button.handle_button_events(event, MouseX, MouseY); 

     for(int i = 0; i < trees.size(); i++) 
     { 
      trees[i].handle_events(event, MouseX, MouseY, Xoffset, Yoffset); 
     } 

     for(int i = 0; i < stones.size(); i++) 
     { 
      stones[i].handle_events(event, MouseX, MouseY, Xoffset, Yoffset); 
     } 

     for(int i = 0; i < bushes.size(); i++) 
     { 
      bushes[i].handle_events(event, MouseX, MouseY, Xoffset, Yoffset); 
     } 

     if(event.type == SDL_QUIT) { 
      running = false; 
     } 

     if(event.type == SDL_KEYDOWN) { 
      switch(event.key.keysym.sym) { 
      case SDLK_ESCAPE: 
       running = false; 
      } 
     } 

     if(exit_button.clicked) { 
      running = false; 
     } 

     if(menu_button.clicked) { 
      paused = true; 
     } 


    } 

樹是包含地圖

+0

你也可以說經過SDL_Event到'樹:: handle_events()'的代碼?你有一個析構函數,'Tree ::〜Tree()'? – svk

+0

你確定你叫這個方法嗎? –

+0

我有一個空的析構函數Tree ::〜Tree(){}。至於傳遞的代碼,它位於主遊戲循環中。我把它張貼在第二個 – user2466076

回答

1

delete this實際上不清理還存在對象的指針上的所有樹木的向量。 (它確實調用了析構函數 - 但是因爲你有一個空的析構函數,所以在這裏也不會完成這樣的清理。)在delete this之後,在trees向量中仍然會有一個指向已刪除樹的(懸掛!)指針。

使用此指針的一個可能結果是該樹仍然出現,另一種可能性是崩潰。無法僅使用指針從有效指針中指出懸掛指針。

由於這個原因,delete this往往是一個壞主意,從來沒有一個簡單的解決方案。

您可以考慮檢查樹是否已經從調用handle_events()的函數中耗盡木頭 - 然後您可以刪除樹,也可以從矢量中刪除指針。

+0

這是合成樹可以刪除樹對象: trees [i]。〜Tree(); – user2466076

+0

不,這是對析構函數的顯式調用,它不能解決任何問題。問題不在於對象沒有被正確刪除,而是。問題在於你仍然保留着一個指向過去的指針。查看'vector'的文檔(或者其他答案),看看如何從一個向量中移除一個元素(例如從一個向量的樹*)。 – svk

2

什麼是treestrees[i]?我認爲這是std::vector<Tree*>或類似?

當您致電delete this時,您將刪除trees[i]引用的對象,但不會刪除向量中的條目。刪除後trees[i]指向某些釋放的內存,如果不被別的東西覆蓋 - 仍然看起來像樹對象。

我建議做這樣的事情:

for(int i = trees.size()-1; i >= 0; i--) { 
    trees[i].handle_events(event, MouseX, MouseY, Xoffset, Yoffset); 
    if (trees[i].isEmpty()) { 
     delete trees[i]; 
     trees.erase(trees.begin()+i); 
    } 
} 

注意,從最終迭代是很重要的,因爲當元素被刪除,所有的後續工作將被轉移。

如果矢量很大,而且你做了很多刪除操作,考慮使用不提供隨機訪問的不同結構,因爲從矢量中刪除可能非常耗時。


更新: 我假設成員函數Tree::isEmpty()由你來實現與邏輯指定當對象是空的,不再需要的,但並沒有實際刪除的對象。它們的

因爲,就像你說的,treesTree對象的矢量,而不是指針,你應該從未自行刪除這些對象!矢量是這些對象的所有者,它將刪除它們。

出於這個原因,你應該叫trees.erase(trees.begin()+i),它會丟棄的對象。

+0

樹是地圖上所有樹對象的向量。 這給我2錯誤說: | 272 |錯誤:'類樹'沒有名爲'isEmpty'的成員| 和 | 273 | error:type'class Tree'argument'delete',expected pointer | – user2466076

+0

樹木是一個矢量對象,不是指針 – user2466076

+0

那麼......它不工作。樹保持在原來的位置 編輯: 我在if中寫了'='而不是'=='。現在它完美地工作。非常感謝你! – user2466076