[英]C++ Destructors with Vectors, Pointers,
據我所知,我應該在析構函數中銷毀我用new
和關閉的打開文件流和其他流創建的所有內容。 但是,我對C ++中的其他對象有些懷疑:
std::vector
和std::string
s:它們會自動銷毀嗎?
如果我有類似的東西
std::vector<myClass*>
指向類的指針。 調用向量析構函數時會發生什么?
它會自動調用myClass
的析構函數嗎? 或者只有矢量被破壞,但它包含的所有對象仍然存在於內存中?
如果我有一個指向類中另一個類的指針會發生什么,比如說:
class A { ClassB* B; }
並且在代碼中的某個點銷毀A類。 B類是否會被銷毀,或者只是指針和B類仍將存在於內存的某個地方?
std :: vector和std :: strings:它們會自動銷毀嗎?
是(假設成員變量不是指向std::vector
和std::string
指針)。
如果我有像std :: vector這樣的東西,那么在調用向量析構函數時會發生什么? 它會自動調用myClass的析構函數嗎? 或者只有矢量被破壞,但它包含的所有對象仍然存在於內存中?
如果vector<MyClass>
那么包含在向量中的所有對象都將被銷毀。 如果vector<MyClass*>
則必須顯式delete
所有對象d(假設被破壞的類擁有vector
的對象)。 第三種選擇是vector
智能指針,如vector<shared_ptr<MyClass>>
,在這種情況下的元素vector
不需要顯式地delete
d。
如果我有一個指向類中另一個類的指針會發生什么
B
必須明確delete
d。 同樣,可以使用智能指針來處理B
的破壞。
您只需要擔心動態創建的內存(當您使用new
保留內存時。)
例如:
Class Myclass{
private:
char* ptr;
public:
~Myclass() {delete[] ptr;};
}
這取決於。 std::vector
和std::string
和MyClass
都有一個共同點 - 如果你聲明一個變量是這些類型中的任何一個,那么它將在堆棧上分配,對於你所在的當前塊是本地的,並且當那個街區結束時被破壞。
例如
{
std::vector<std::string> a;
std::string b;
MyClass c;
} //at this point, first c will be destroyed, then b, then all strings in a, then a.
如果你得到指針,你猜對了:只有指針本身占用的內存(通常是4字節整數)將在離開范圍時自動釋放。 除非您明確delete
它(無論它是否在向量中),否則指向的內存沒有任何反應。 如果你有一個包含指向其他對象的指針的類,你可能必須在析構函數中刪除它們(取決於該類是否擁有這些對象)。 請注意,在C ++ 11中有一些指針類(稱為智能指針),可以讓您以與“普通”對象類似的方式處理指針:
例如:
{
std::unique_ptr<std::string> a = make_unique<std::string>("Hello World");
function_that_wants_string_ptr(a.get());
} //here a will call delete on it's internal string ptr and then be destroyed
如果他們是自動存儲,是的。 你可以使用std::string* s = new std::string
,在這種情況下你必須自己刪除它。
沒有,你需要手動刪除你擁有的內存(用於分配new
內存)。
如果你用new
分配了b
,你應該在析構函數中明確地銷毀它。
一個好的經驗法則是對代碼中的每個new/new[]
使用delete/delete[]
。
一個更好的經驗法則是使用RAII,並使用智能指針而不是原始指針。
如果我有像std :: vector這樣的東西,那么在調用向量析構函數時會發生什么?
這取決於。
如果你有一個值為 std::vector <MyClass>
,那么向量的析構函數會為向量中的每個MyClass
實例調用析構函數。
如果你有一個指針向量std::vector <MyClass*>
,那么你負責刪除MyClass
的實例。
如果我有一個指向類中另一個類的指針會發生什么
ClassB
實例將保留在內存中。 使ClassA
析構函數為您完成工作的可能方法是使B
成為實例成員或智能指針。
std::vector
, std::string
,據我所知,所有其他STL容器都有自動析構函數。 這就是為什么通常更好地使用這些容器而不是new
和delete
因為您將防止內存泄漏。
只有當你的向量是myClass
對象的向量( std::vector< myClass >
)而不是指向myClass
對象的指針向量( std::vector< myClass* >
)時,才會調用myClass
析構函數。
在第一種情況下, std::vector
的析構函數也會為每個元素調用myClass
的析構函數; 在第二種情況下, std::vector
的析構函數將調用myClass*
的析構函數,這意味着它將釋放用於存儲每個指針的空間,但不會釋放用於存儲myClass
對象本身的空間。
您指向的Class B
對象不會被銷毀,但分配用於存儲其指針的空間將被釋放。
是。 std::vector
和std::string
在超出范圍時自動調用,也調用包含的對象的析構函數(對於std::vector
)。
如前所述, std::vector
在超出范圍時被銷毀,調用所包含對象的析構函數。 但事實上,在這種情況下,包含的對象是指針,而不是指針指向的對象。 所以你必須手動delete
它們。
與(2)相同。 A將被銷毀,所以指針,但不是B類指向。 您必須為delete
B的A提供析構函數。
在C ++ 11中有一個非常有用的解決方案:使用std::unique_pointer
。 可以僅用於指向單個對象,當指針超出范圍時(例如,當您銷毀std::vector
),這將被刪除。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.