當物體a
被破壞時,personsInHouse
地圖是否也被銷燬或者我需要在析構函數中銷燬它?如果我不這樣做會造成內存泄漏嗎?當類被銷燬時,在類中聲明的映射容器是否被銷燬?
class A {
public:
map<unsigned int, unsigned int> personsInHouse;
};
int main(){
A a;
A.hash[10] = 23;
};
當物體a
被破壞時,personsInHouse
地圖是否也被銷燬或者我需要在析構函數中銷燬它?如果我不這樣做會造成內存泄漏嗎?當類被銷燬時,在類中聲明的映射容器是否被銷燬?
class A {
public:
map<unsigned int, unsigned int> personsInHouse;
};
int main(){
A a;
A.hash[10] = 23;
};
是的。當一個類的析構函數運行時,其所有成員的析構函數都會運行。準確地說,該順序爲:
一般來說,如果你沒有指針,你可以期望也沒有內存泄漏。情況並非總是如此:您可能正在使用漏泄函數,或者某個函數可能正在執行動態分配,然後返回對該對象的引用。使用智能指針可以進一步改善情況。
用於避免C++中的內存泄漏的有用技術是RAII:所有標準容器都遵循它,這就是爲什麼不需要在容器超出範圍之前明確指定容器的原因。基本原則是讓類在其析構函數中清理所有資源,然後爲此專門製作類,以便大多數類不需要擔心。
請注意「類成員」是在類作用域中定義的嚴格非靜態成員。如果你有
struct S {
int* p;
};
然後p
是S
的唯一部件,並且在S
超出範圍,p
將被銷燬(這通常不涉及任何事情發生,也許除了堆棧指針的調整) 。如果你在某一時刻做了S s; s.p = new int;
那麼p
仍然是唯一的成員,而p
指向的對象將是而不是是1,因此當s
超出範圍時不會被銷燬。爲此,您需要手動執行delete s.p;
,這對應於每個new
需要對應的delete
(同上new[]
和delete[]
)的一般規則。
如果其成員處於動態存儲中,該怎麼辦? – 2012-02-19 15:07:06
@LuchianGrigore:那麼這不是一個成員,而是一個指向對象的成員指針。正如我所說,指針被破壞了。 – 2012-02-19 15:09:13
@LuchianGrigore:成員不能在堆中,他們可以指向堆中的項目(在這種情況下,指針本身實際上被銷燬,但不是它指向的內容) – Jack 2012-02-19 15:09:57
的personsInHouse
壽命是自動因爲你被值存儲它,並且它的壽命是父對象的壽命。因爲按值創建了a
,所以它的析構函數在超出範圍時被調用,並且對象的析構函數會自動調用它所包含的對象的析構函數。所以你不需要銷燬personsInHouse
,就像你不需要銷燬a
一樣。
如果personsInHouse
是指針和您創建了一個map<unsigned int, unsigned int>
在動態存儲與new
和存儲的指針,它在personsInHouse
,那麼你就需要手動解除對其personsInHouse
是指向內存中的析構函數A
via delete
。但是您發佈的代碼並非如此。
你所做的是做到這一點的好方法:更願意按價值存儲每個對象,以便不必擔心動態對象的生命週期管理。
從技術上講,personsInHouse的範圍是父對象的範疇。但除此之外,一個詞彙詞,答案是好的。 – 2012-02-19 15:08:23
@MooingDuck最好說「生命」,不是嗎?我認爲範圍更多的是可見性。謝謝,我又添加了一行。 – 2012-02-19 15:11:23
@Seth:的確如此。 – molbdnilo 2012-02-19 15:39:16
[相關常見問題](http://stackoverflow.com/questions/6403055/) – fredoverflow 2012-02-19 16:42:29