2010-02-10 62 views
1

這是this question的擴展。我在網上搜索,但無法找到滿意的答案。刪除向量中的元素(對象)(未由指針引用),內存處理

我有一個class A它定義了一個向量,其中包含多個class Region的實例。該內存處理這些Region情況下需要由Class A

我的問題管理是:

在下面的代碼片段,我需要在A類desctuctor明確刪除這些實例?

2.我應該創建new Region(i)的實例嗎?是否比第一個選項更好(不使用new)A類是一個相當大的對象。我應該如何確定是否使用新的?

3.如果對#2的回答是肯定的,我應該如何在析構函數中刪除這些實例? delete Region(i)(在for循環中)或delete [] reg ??我猜以前的方式是正確的方式,但要確認。

4.除了「區域實例不被刪除」,你是否看到任何明顯的內存泄漏......特別是在A的構造函數中構造Region對象?

class Region{ 
    public: 
     Region(int num); 
     int number; 
     std::vector <elemt*> elements; 
     int info; 
} 

class A{ 
public: 
    std::vector<Region> reg; 
    const int numOfRegions = 100; 
} 

A::A(){ 
    int i; 
    for (i=0; i<numOfRegions; i++){ 
     reg.push_back(Region(i)); 
     } 
} 

A::~A(){ 
    // How should the elements within vector Region be deleted?? 
    // Should I use "new" to allocate memory to instances of Region() 
} 

UPDATE: 非常感謝所有誰回答!

回答

3

在下面的代碼片段,我需要在課堂上 A的desctuctor明確刪除這些 實例?

否 - 它們將被自動刪除 - 如果您不用新創建它,則不會刪除它。

我應該創建實例作爲新的區域(i)嗎?是否比 第一個選項更好(不使用新的)A類 是一個相當大的對象。 如何確定是否使用新的?

A的大小不是問題。這個問題沒有明確的答案,但一般規則是,如果您不必使用new動態創建對象,則不要這樣做。

如果對#2的回答是肯定的,我應該如何在 析構函數中刪除這些實例?刪除區域(i)(在 中for循環)或刪除[] reg ??我是 以前的方式猜測是正確的 的方式,但是想確認一下。

如果您在使用新創建它們,你就會刪除他們在一個for循環:

delete reg[i]; 

REG必須是當然的指針的載體。更好的選擇是使用智能指針向量。

除「地區的實例不會被刪除」,你看不到任何明顯的 內存泄漏..特別是在A的 構造的 建設區域對象?

他們被刪除 - 只是不是你。這就是所謂的RAII,它是非常非常好的C++實踐 - 你應該儘可能使用RAII。

+0

@尼爾:很好的答案。你們是非常有幫助的(並且總是在那裏尋求幫助)。我只是有一個疑問,在上面的代碼中,我已經說明了Region實例是在類A的構造函數中添加的。但是,如果我要在運行時通過調用類A上的方法來填充此列表: :addRegions(int num),我應該在這種情況下使用「新」嗎?或者我應該堅持使用當前的代碼? – memC 2010-02-10 12:08:00

+1

@memC:它是確定如何向其中添加項目的向量。如果在構造函數中:'reg.push_back(Region(i))',那麼您需要類似於'A :: addRegions(int num);'方法的東西。所以我說的還是不要使用'new'。 – quamrana 2010-02-10 12:14:30

+0

@memC您可以在施工時或以後進行。當然,你將不得不提供一個成員函數來完成它。無論哪種情況,都不需要使用新建對象。 – 2010-02-10 12:15:23

3
  1. std::vector存儲Region S作爲對象並調用時元素被添加/移除/覆蓋必要的(DE)的構造。

  2. 不,只有你聲明你的向量爲std::vector<Region *> reg;。如果Region是多態的,或者複製/分配構造函數很昂貴(矢量經常會複製元素),則必須這樣做。

  3. 如果將它們存儲爲指針,則需要遍歷reg,並使用delete ptr;刪除每個元素。

  4. 根據您創建elemt -class的實例的方式,您可能需要將一個析構函數添加到Region以銷燬這些實例。

+0

+1,但請編輯您的答案以將解構器更改爲析構函數。 – quamrana 2010-02-10 12:06:01

+0

謝謝ebo ...你所有的答案都非常有用。請看我對尼爾的回答.. – memC 2010-02-10 12:10:13

1

裏面class A一切似乎都被確定好了。 (你需要整理類聲明)。這意味着當A的一個實例被銷燬時,所有東西都會被自動銷燬。是的,我的意思是std::vector reg;本身就會銷燬,並且它負責的所有Region副本都會銷燬。

你真的在問關於class Region和它的vector哪些指針,雖然你沒有顯示任何代碼可能需要它的指針刪除?

編輯:

第一編輯包含的Region細節,第二編輯刪除它們,並添加A::addRegions

我想這是你所追求的:

#include <vector> 

class Region{ 
    public: 
     Region(int num); 
     // Details of Region removed 
}; 

class A{ 
    std::vector<Region> reg; 
    const int numOfRegions; 
public: 
    A(); 
    // No destructor needed: ~A(); 
    void addRegions(int num); 
}; 

A::A():numOfRegions(100){ 
    for (int i=0; i<numOfRegions; ++i){ 
     reg.push_back(Region(i)); 
     } 
} 
void A::addRegions(int num) 
{ 
    for (int i=0; i<num; ++i){ 
     reg.push_back(Region(i)); 
    } 
} 

注意class A沒有析構函數。

A::addRegions還採用push_back即使現在不需要析構函數。

另請注意,類聲明如何在它們後面有分號,並且A的構造函數初始化爲numOfRegions

+0

不,我*不*詢問類地區及其向量。你的答案就是我所需要的......然而,現在我很困惑我應該使用「新」還是保持代碼的方式。 (由於@MSalters評論而感到困惑)誰應該處理Region對象的刪除?是否使用「新」更好的做法?如果是這樣,我是否也應該刪除〜A()中的那些...或者它會被矢量本身處理嗎? – memC 2010-02-10 12:03:22

+1

您所指示的最佳做法是讓'std :: vector'負責管理'Region'實例的內存。 – quamrana 2010-02-10 12:04:59

+0

yeap,我明白了..謝謝!您能否回答這個問題(在Neeils回覆中添加了一條評論):「在這個例子中,我說明了Region實例是在A類的構造函數中添加的。但是,如果我要填充這個列表,通過調用類A :: addRegions(int num)上的方法,我應該在這種情況下使用「new」還是應該堅持使用當前的代碼? – memC 2010-02-10 12:13:33

1

1.在您的示例中,您需要明確刪除的唯一內容是elemt*,如果它們是動態分配的。如果是這樣,它們必須由它們擁有而被刪除。如果您的Region僅指向它們,則不應在其析構函數中刪除它們。

2.首先,你的向量被分配在堆棧中,並且將被釋放而沒有問題。其次,要使用new Region(i),您需要更改class A聲明。但在你的情況下沒有必要這樣做。舉幾個例子,當你應該使用operator new
1)的必要性,更持久數據是必需的,因爲你的動態分配的數據會繼續下去,直到可明確釋放(和acessible只要你保持一個指針指的是)
2)您的對象可能太大而無法全部存儲在堆棧中。

3.如果你沒有使用new Region(i),你會使用operator delete在某些時候,可能在析構函數或其他清理功能,正確取消此分配。只有當你在你的elements載體即elements.push_back(new elemt())直接創建新elemt,例如

4.你的構造會出現問題。這是一種危險的設計,可能會導致幾次內存泄漏或seg故障風險。如果你想以這種方式分配它們,你需要一個支持複製機制的智能指針,如shared pointer

相關問題