2009-06-17 96 views
1

我使用borland 2006 C++,並且有以下代碼。我正在使用矢量,並且無法理解爲什麼析構函數沒有被調用。stl向量內存管理

基本上我有一個A類

class A 
{ 
private: 
    TObjectList* list; 
    int myid; 
public: 
__fastcall A(int); 
__fastcall ~A(); 
}; 

__fastcall A::A(int num) 
{ 
    myid = num; 
    list = new TObjectList(); 

} 

__fastcall A::~A() 
{ 
    delete list; 
} 

int main(int argc, char* argv[]) 
{ 
    myfunc(); 
    return 0; 
} 

void myfunc() 
{ 
    vector<A*> vec; 
    vec.push_back(new A(1)); 
    vec.push_back(new A(2)); 
} 

根據我讀,變量時VEC在MYFUNC(),它應該破壞其所含元素,超出範圍,從而對於A析構函數應該被稱爲。我在〜A()斷點,但從來沒有被調用,我已經嘗試調整大小(),清除方法也

TIA

回答

15

VEC當它超出範圍並銷燬其元素。這裏的問題是vec的元素是指針到A對象,而不是對象本身。如果你反而做

vector<A> vec; 
vec.push_back(A(1)); 
vec.push_back(A(2)); 

...然後事情會按預期工作。

ETA:但是請注意,如果你這樣做,你必須定義答:這應該包括做TObjectList成員的深層副本拷貝構造函數。否則,當你複製一個A對象時,你會得到兩個指向同一個TObjectList的對象,並且當第二個對象被銷燬時,你的程序會崩潰。

+2

作爲一個方面說明。不要嘗試使用auto_ptr來在容器內使用指針時執行破壞。 Auto_ptrs無法在STL容器內使用,因爲它們被複制的方式。 – 2009-06-17 19:45:43

3

A析構函數不叫,因爲你沒有的A的向量。你有一個指向A的指針向量,並且指針的析構函數被調用。指針沒有析構函數,所以沒有任何反應。刪除一切

一種方式是手工做類似

while (!vec.empty()) 
{ 
    delete vec.back(); 
    vec.pop_back(); 
} 
1

抓住Boost庫,並且無論你在有一個原始指針上面你使用boost :: shared_ptr的<>代替。 (哦,不是在main()的簽名)

3

很多很好的答案已經,但我會增加一個:

使用的boost ::從Boost Pointer Container Library ptr_vector,而不是性病: :向量。它將在向量超出範圍時刪除對象,從而調用析構函數。