2011-03-26 74 views
5

這是正確的?:刪除從動態的std ::矢量分配的對象

std::vector<Enemy*> enemies; 
enemies.push_back(new Enemy()); 

Enemy* enemy = enemies[0]; 
enemies.erase(enemies.begin() + 0); 
delete enemy; 
+7

通常情況下:考慮使用共享指針或boost :: ptr_vector的向量。 – 2011-03-26 21:39:36

+1

這裏是boost指針容器的鏈接,Space_C0wb0y正在討論:http://www.boost.org/doc/libs/1_46_1/libs/ptr_container/doc/tutorial.html#basic-usage – yasouser 2011-03-26 21:47:20

+2

你'push_back(新敵人)'?難道你不知道把你的敵人推到後面是不公平的嗎? :-D – 2011-03-26 21:50:10

回答

8

它的作品,是的,但它不是一個理想的方法。

首先,加0就是噪音,你可以刪除它。但更好的是,只需使用pop_front()即可。另外,不需要中間步驟,您可以在刪除之前刪除。

但是std::vector不如從前面彈出,尤其是如果它很大(因爲其餘元素需要移動以填補空白)。如果您不需要連續內存,請改用std::deque。或者,如果順序並不重要,你可以使用這樣的事情:

template <typename T, typename A> 
void unordered_pop_front(std::vector<T, A>& vec) 
{ 
    using std::swap; 
    swap(vec.front(), vec.back()); // constant time 

    vec.pop_back(); // constant time 
} 

它交換與背面元件的正面元素,然後彈出它關閉。當然,訂單不會保留。

另一個問題是你的內存管理方法。任何時候你有明確的清理代碼,你做錯了什麼。它應該是done automatically

使用Boost's ptr_vectorstd::vectorsmart pointers。 (注意:不要在容器中使用std::auto_ptr,在這方面它會被破壞。)要獲得快速智能指針建議,請使用std::unique_ptr(如果您的編譯器支持C++ 0x)或std::/boost::shared_ptr

1

是的,這很好。你可以把它簡化一點:

delete enemies[0]; 
enemies.clear(); 

對於刪除元素,你也可以使用:

enemies.pop_back(); 

或(非常類似於你):

enemies.erase(enemies.begin()); 
+0

什麼叫〜敵人()?它是vector.erase()/ vector.clear()還是它是刪除敵人[0]? – Ryan 2011-03-26 21:45:16

+1

@Ryan:'delete'調用指向對象的析構函數,然後釋放內存。 – GManNickG 2011-03-26 21:45:51

2

當然看起來罰款我。您不需要enemies.erase系列中的+ 0,但除此之外,它完全可以。

4
std::vector<Enemy*> enemies; 
enemies.push_back(new Enemy()); 

這不是異常安全的。如果push_back未能分配足夠的內存來容納新指針,則Enemy對象會泄漏。

使用智能指針的載體可以解決這個問題,但是做不到這一點,你應該推回前預留空間向量:

std::vector<Enemy*> enemies; 
enemies.reserve(1); // or more generally, enemies.reserve(enemies.size()+1); 
enemies.push_back(new Enemy()); 

現在我們知道,push_back不能不分配內存,並如果reserve失敗,則在創建Enemy之前拋出異常。