2011-08-24 54 views
8

來自C#世界,我努力確保我不會在我分配的C++項目中引入內存泄漏和錯誤。我正在編寫使用結構來解析來自數據緩衝區的信息的代碼。由於緩衝區中出現的數據結構數量在運行時會有所不同,因此使用stl向量來存儲處理後的數據。我在現有的軟件跨越下面的代碼塊來了,我在努力理解爲什麼它的工作原理:管理STL向量中的作用域和對象生命週期

MyVectorOfObjects.clear(); 
for (unsigned __int8 i = 0; i < NumberOfObjects; i++) 
{ 
    MyParserObject parserObject;    // Declaring without 'new'? 
    parserObject.Decode(buffer, offset, size); // A method on the struct. 
    MyVectorOfObjects.push_back(parserObject); // Does this keep parserObject in scope? 
} 

我的問題是明確:

  1. this question,不會parserObject去由於new關鍵字未被使用,因此每次迭代超出範圍?顯然這個代碼一直在工作。

  2. 在這種情況下,是否將對象放置在vector中使parserObject保持在範圍內?根據this question,parserObject被複制。如果是這樣的話,那麼這對性能的影響(如內存消耗,內存分配等)是什麼?另外,複製的parserObjects然後假設與向量相同的範圍?

感謝您的任何幫助。

+3

這是一些基本的C++。我建議抓住[良好的入門C++書](http://tinyurl.com/so-cxxbooks)並從中學習。也就是說,你需要認識到C++和C#之間的一個很大的區別:在C++中,變量包含* values *(當然,除非顯式聲明爲引用),而在C#中,大多數變量包含*引用*(當然,不包括值類型)。 –

+0

通過'MyParserObject parserObject',它的內存被程序自動管理 - 把它想象成一個'delete parserObject;'在'for'循環之後,儘管這在實踐中並不一定發生。 –

+0

@ R.Martinho感謝您的參考...和筆記。 – bporter

回答

7
  1. 是的,這是for循環內聲明的parserObject實例每次超出範圍的循環迭代。

  2. 不,將parserObject放入vector不會將該對象保留在範圍內。 push_back()方法將複製vector現在擁有的對象。您需要確保您的對象可以正確複製(可能需要複製構造函數和賦值運算符)。此示例中包含在矢量中的副本由矢量所有,並且具有與vector本身類似的對象生命週期。

  3. 複製了paserObject,這可能會影響內存使用情況和性能。如果parserObject不是微不足道的複製,那麼這可能是一個昂貴的操作。這完全取決於您執行parserObject

+0

兩個很好的答案,我希望我可以接受;被迫選擇,但是,這一個明確地回答了這些問題。感謝所有人的幫助。 – bporter

4
MyVectorOfObjects.push_back(parserObject); // Does this keep parserObject in scope? 

push_back製作對象的副本並存儲它。

因此,確保您已經爲類MyParserObject正確定義了複製構造函數(和複製分配),如果它具有指針成員。否則編譯器生成的默認代碼就足夠了,只要MyParserObject的每個成員都遵循相同的模式(即,如果它們具有指針成員,或者默認代碼已經定義了複製構造函數(和複製賦值)由編譯器生成的就足夠了,只要....等等。)

+0

因此,這意味着只要MyVectorOfObjects在範圍內,每個複製的parserObject都會保留在範圍內? – bporter

+0

@bporter。是的。 – Nawaz

+1

如果你使用C++ 0x,那麼也一定要定義move-constructor和move-operators。 –