2010-04-29 89 views
3

我在A類中有兩個包含其他類對象B和C的向量。我知道這些向量最多應該保存多少個元素。在類A的構造函數的初始化列表中,我將這些向量初始化爲其最大大小(常量)。C++中真正的空std :: vector是什麼?

如果我正確地理解了這一點,我現在有一個B類對象的向量,它們已經使用它們的默認構造函數進行了初始化。對?當我編寫這段代碼時,我認爲這是處理事情的唯一方法。不過,我已經瞭解了std::vector.reserve(),並且我想實現不同的目標。

我想分配內存,因爲增加了他們通過用戶輸入來控制這些載體儘可能大的成長,所以我不想頻繁resizings。但是,我每秒迭代遍歷這個向量很多次,而且我目前只處理標記爲「活動」的對象。必須在每次迭代中檢查B/C類的布爾成員是愚蠢的。我不希望這些對象甚至可以在我的迭代器中看到,當我通過這個列表運行時。

超前預留空間最大的時間和使用push_back到一個新的對象添加到載體中的解決方案呢?

+3

是否確定,有可能是一個性能問題,而且它很可能是在那裏? – 2010-04-29 16:19:44

+0

@DavidThornley這不僅僅是一個性能問題,它是一個基本的C++問題。默認值應該是永遠不會創建無效但存在的對象。您不必衡量從「錯誤的方式」到「正確的方式」來證明切換的性能;你必須測量它來證明不切換。 – 2013-01-05 17:19:42

回答

12

A vector有容量和它的大小。容量是已分配內存的元素的數量。大小是實際在矢量中的元素的數量。 A vector當它的大小爲0時爲空。因此,size()返回0並且empty()返回true。這並沒有說明當時的vector的容量(這取決於自創建以來對vector所做的插入和擦除次數)。 capacity()會告訴你當前的容量 - 也就是vector必須重新分配其內部存儲空間才能容納更多的元素的數量。

所以,當你構建一個vector,它具有一定的規模和一定的能力。默認構建的vector將具有零大小和實現定義的容量。您可以將元素融入vector自由而不必擔心vector是否足夠大 - 高達max_size() - max_size()是最大容量/大小,一個vector可以有系統(通常是足夠大,不用擔心)上。每次將項目插入vector時,如果它具有足夠的容量,則不會將內存分配分配給vector。但是,如果插入該元素將超過vector的容量,則會在內部重新分配內存,以便它具有足夠容量來容納新元素以及實現定義數量的新元素(通常, vector可能會翻​​倍),並且該元素被插入到向量中。發生這種情況時,您不必擔心增加vector的容量。它發生在constant amortized time,所以你通常不需要擔心它是一個性能問題。

如果您發現您經常添加到vector以至於發生許多重新分配,並且這是一個性能問題,那麼您可以撥打reserve(),這會將容量設置爲至少給定的值。通常情況下,當你很清楚你的vector可能有多少元素時,你會這樣做。然而,除非你知道它會出現性能問題,否則這可能是一個壞主意。這隻會讓你的代碼複雜化。並且constant amortized time通常會足夠好以避免性能問題。

你也可以用你提到的給定數量的默認構造元素構造一個vector,但除非你真的想要這些元素,那麼這將是一個壞主意。 vector應該是這樣的,以便在向其中插入元素時不必擔心重新分配容器(就像您必須使用數組一樣),並且爲了分配內存而默認構建元素是打敗了這一點。如果你真的想這樣做,請使用reserve()。但是,除非您確定它會提高性能,否則請不要打擾reserve()。正如在另一個回答中指出的那樣,如果您基於用戶輸入將元素插入到vector,那麼很可能是I/O的時間成本將遠遠超過爲那些相對於vector重新分配內存的時間成本罕見的情況下,當它的容量耗盡。

能力相關的功能:

capacity() // Returns the number of elements that the vector can hold 
reserve() // Sets the minimum capacity of the vector. 

大小相關的功能:

clear() // Removes all elements from the vector. 
empty() // Returns true if the vector has no elements. 
resize() // Changes the size of the vector. 
size() // Returns the number of items in the vector. 
+0

真的是一個很好的完整anwer,+1。 – 2010-04-29 17:06:00

+0

感謝您的好評。 :)學到的東西比我直接要求的要多得多,這就是我喜歡SO的原因。 – RyanG 2010-04-29 17:47:45

+0

+1,但還有另外一個原因使用'reserve':如果元素被插入,迭代器,引用和指向vector中元素的指針就會失效,除非你使用'push_back'和'vec.size() rlbond 2010-04-29 17:56:21

4

是的,reserve(n)將分配空間,但實際上並沒有將元素放在那裏 - 增加capacity()而不增加size()

順便說一句,如果「增加了他們通過用戶輸入控制」是指用戶點擊「插入X」,而插入X到載體,你不必擔心調整的開銷。等待用戶輸入比調整大小的性能慢很多倍。

1

你的問題有點令人困惑,所以讓我試着回答我認爲你問的問題。

比方說你有一個默認構造的vector<B>。您然後致電vec.reserve(100)。現在,vec包含0個元素。它是空的。 vec.empty()回報truevec.size()返回0每次調用push_back時候,你會插入一個元素,除非vec conatins 100元,就沒有再分配。

相關問題