簡體   English   中英

帶向量,指針的C ++析構函數,

[英]C++ Destructors with Vectors, Pointers,

據我所知,我應該在析構函數中銷毀我用new和關閉的打開文件流和其他流創建的所有內容。 但是,我對C ++中的其他對象有些懷疑:

  • std::vectorstd::string s:它們會自動銷毀嗎?

  • 如果我有類似的東西

     std::vector<myClass*> 

    指向類的指針。 調用向量析構函數時會發生什么?
    它會自動調用myClass的析構函數嗎? 或者只有矢量被破壞,但它包含的所有對象仍然存在於內存中?

  • 如果我有一個指向類中另一個類的指針會發生什么,比如說:

     class A { ClassB* B; } 

    並且在代碼中的某個點銷毀A類。 B類是否會被銷毀,或者只是指針和B類仍將存在於內存的某個地方?

std :: vector和std :: strings:它們會自動銷毀嗎?

是(假設成員變量不是指向std::vectorstd::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::vectorstd::stringMyClass都有一個共同點 - 如果你聲明一個變量是這些類型中的任何一個,那么它將在堆棧上分配,對於你所在的當前塊是本地的,並且當那個街區結束時被破壞。

例如

{
    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::vectorstd::string ,據我所知,所有其他STL容器都有自動析構函數。 這就是為什么通常更好地使用這些容器而不是newdelete因為您將防止內存泄漏。

只有當你的向量是myClass對象的向量( std::vector< myClass > )而不是指向myClass對象的指針向量( std::vector< myClass* > )時,才會調用myClass析構函數。

在第一種情況下, std::vector的析構函數也會為每個元素調用myClass的析構函數; 在第二種情況下, std::vector的析構函數將調用myClass*的析構函數,這意味着它將釋放用於存儲每個指針的空間,但不會釋放用於存儲myClass對象本身的空間。

您指向的Class B對象不會被銷毀,但分配用於存儲其指針的空間將被釋放。

  1. 是。 std::vectorstd::string在超出范圍時自動調用,也調用包含的對象的析構函數(對於std::vector )。

  2. 如前所述, std::vector在超出范圍時被銷毀,調用所包含對象的析構函數。 但事實上,在這種情況下,包含的對象是指針,而不是指針指向的對象。 所以你必須手動delete它們。

  3. 與(2)相同。 A將被銷毀,所以指針,但不是B類指向。 您必須為delete B的A提供析構函數。

在C ++ 11中有一個非常有用的解決方案:使用std::unique_pointer 可以僅用於指向單個對象,當指針超出范圍時(例如,當您銷毀std::vector ),這將被刪除。

http://en.cppreference.com/w/cpp/memory/unique_ptr

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM