2015-11-06 36 views
4

比方說,我有一個這樣的結構:通過值傳遞的C++向量:我得到它的權利?

struct typeA 
{ 
    long first; 
    string second 
    double third; 
}; 

如果我宣佈

typeA myArray[100]; 

然後myarray的存儲在堆棧中,消耗的sizeof(的typeA)* 100個字節的垃圾數據(直到我存儲一些實際的數據,至少)。

每當我將這個數組作爲參數傳遞時,我總是將指針傳遞給堆棧中第一個元素的第一個元素。所以指針從棧到堆棧。

但是,如果我聲明

vector<int> myVector (4, 100); 

然後myVector對象實際上存儲在堆棧中,它包含一個指向的4 *的sizeof(int)的數組的第一元素的字節存儲在堆,在那裏存儲實際的數據。所以指針從棧到堆。

每當我通過這個載體作爲參數,如果我把它添加到參數列表如下:

vector<int> parameterVector 

功能得到myVector對象,並將其存儲在堆棧中的副本。

但是,如果我不喜歡這樣寫道:

vector<int> &parameterVector 

的功能得到了參考myVector存儲在堆棧中,所以我現在都存儲在堆棧中的變量,引用也存儲在myVector對象在堆棧中,它包含一個指向存儲在堆中的實際元素數組的指針。

這是正確的嗎?

我有幾個疑惑這裏:

  1. 做實際的元素,會存儲在一個靜態數組(由C繼承而來的,用方括號表示)在堆中?
  2. myVector對象是否只有一個指向第一個元素的指針,或者它有多個指向每個元素的指針?
  3. 因此,按值傳遞一個向量不會帶來很大的問題,因爲唯一被複制的是矢量對象,但不是實際的元素。是這樣嗎?
  4. 如果我弄錯了所有的東西,並且實際的元素也被複制以及通過值傳遞向量參數,那麼爲什麼C++允許這樣做,考慮到它會阻止它與靜態數組? (據我所知,靜態數組總是作爲參考傳遞給第一個元素)。

謝謝!

+0

如果按值傳遞一個向量,則元素也會被複制 –

+2

聲明'vector&parameterVector'聲明'parameterVector'是'typeA'元素的向量的引用*,而不是指針。 –

+1

而關於'vector myVector(4,100)',那不是一個有效的聲明。它試圖創建一個由四個元素組成的向量,每個元素初始化爲「100」。但是你不能將'typeA'對象初始化爲'100'。 –

回答

2

是否將實際元素存儲在堆中的靜態數組中(從C中繼承,用方括號表示)?

典型地,該向量的元素使用的是動態數組存儲在自由存儲區等

some_type* some_name = new some_type[some_size] 

是否myVector對象僅具有一個指針的第一個元素,或它具有多個指針到每一個元素?

通常情況下,一個向量將有一個指向第一個元素的指針,一個大小變量和一個容量。它可能有更多,但這些是實現細節,並沒有被標準定義。

因此,按值傳遞一個向量不會帶來很大問題,因爲唯一被複制的是矢量對象,而不是實際元素。是這樣嗎?

複製矢量是否爲O(N)操作,因爲它必須複製矢量的每個元素。如果沒有,那麼你將有兩個向量使用相同的底層數組,如果一個被破壞,那麼它會從另一個下面刪除數組。

+3

*「將它看作是按值傳遞的對象」*,除非修改它會影響函數外部的某些內容。 –

+1

「把它看作是一個按值傳遞的對象」 - ** no **:把它當作通過引用傳遞的對象,因爲這就是發生的事情。 –

1
  1. 做實際的元件獲取存儲在一個靜態數組(由C繼承的那些,用方括號表示)在堆中?

std::vector<>將在堆中的所有要素分配內存,因爲,您使用標準分配器。它將管理該內存並在必要時重新分配。所以不,沒有靜態數組。它更像是在C中處理動態數組,但沒有所有陷阱。

如果您正在尋找現代化的C陣列替代品,請看std::array<>。請注意,std::array<>也會複製所有元素。如果這是你的意思,請通過參考。

  • 是否myVector對象僅具有一個指針的第一個元素,或它具有多個指針的元素中的每一個?
  • std::vector通常是一個指向第一個元素,尺寸和用於內部使用幾個更多的比特。但細節實際上是特定於實現的。

  • 因此,通過值傳遞一個矢量不會造成太大的問題,因爲該被複制的唯一事情是矢量對象,但不是實際的元件。是這樣嗎?
  • 否。只要將矢量對象複製到另一個矢量對象,所有元素都將被複制。

  • 如果我得到整個事情錯誤並通過一個向量參數由值時的實際元素被複制,以及,那麼爲什麼C++實現這一點,考慮到它具有阻止它靜態數組?(據我所知,靜態數組總是作爲參考傳遞給第一個元素)。
  • 「靜態數組」是C-Legacy。你應該在新代碼中不再使用它們。如果你想通過引用傳遞一個向量,那麼這樣做並不會複製任何內容。萬一你想要移動向量,移動它,而不是複製它。每當你告訴編譯器,你想複製一個對象,它會。

    好吧,爲什麼這樣呢?

    C行爲在某種程度上與其他語言不一致。當你傳遞一個int時,它會被複制,當你傳遞一個結構時,它將被複制,當你傳遞一個指針時,它將被複制,但是當你傳遞一個數組時,數組不會被複制,而是一個指針到它的第一個元素。

    所以C++的方式更加一致。通過價值複製一切,通過參考不。使用C++ 11移動構造函數,可以通過移動它們來傳遞對象。這意味着,原始矢量將保留爲空,而新的矢量已經接管了原始內存塊的責任。