2010-03-04 124 views

回答

7

您可以分配一個字節塊,然後使用placement new通過拷貝構造函數(當然不是默認構造函數)創建T(您的參數類型)的新實例,當新項目被推送到向量的背面時。這將不允許創建「一個N默認初始化的向量」(這是std :: vector可以做到的 - 這就是爲什麼它需要T有一個默認的構造函數來達到這個目的),但是你可以使向量開始空了,可以把Ts推到他們身上。

+0

我該如何分配空間呢? malloc的? – anon 2010-03-04 05:18:26

+2

@anon:看看'vector'是如何做的......它使用了一個分配器,例如'new_allocator'。在我的(舊的)Cygwin安裝中,它的工作原理是這樣的:'{return static_cast <_Tp*>(:: operator new(__ n * sizeof(_Tp))); }'或'malloc_allocator'這樣做:'__ret = static_cast <_Tp*>(malloc(__n * sizeof(_Tp)));' – Dan 2010-03-04 05:34:24

26

std::vector不需要默認構造函數,因爲它從不使用它。每次需要構建元素時,都會使用複製構造函數來執行此操作,因爲每次需要複製時:現有向量元素或您自己提供的用於通過方法參數進行復制的元素(顯式或隱式地,通過依靠默認參數

你可以寫這樣的一類以完全相同的方式:每次你需要你的數組構造新的元素時,需要用戶進行復印提供的元素。在這種情況下,構建原始元素成爲用戶的責任。

它似乎來自你,如果std::vector「需要」一個默認的構造函數時,它都會只是意味着某個地方你依靠的一些vector小號方法默認參數,即它是誰試圖默認 - 構建一個元素,而不是矢量。矢量本身再也不會嘗試默認構建元素。

爲了避免內存分配過程中的默認構造函數的要求,標準庫分配原料未初始化的內存塊,然後立即複製構造在原始內存塊(這是一件好事new[]不能做的)新的元素。這個功能被封裝在std::allocator類中。您也可以在代碼中使用std::allocator,這意味着「魔術」也即時提供給您。

注:以上內容適用於C++ 11以前版本的C++語言規範。 C++ 11改變了很多東西。並且這些更改確實會創建內部使用默認構造函數的情況。

而且它可能是值得注意的是,即使是原來的C++ 98規範允許實現使用功能,以實現標準庫接口超載代替默認參數。這意味着在形式上可能有一個有效的C++ 98實現std::vector,它使用默認構造函數內部

+3

另一方面,它們確實使用了一些非常相關的魔法:std ::分配器對象。 – 2012-04-21 00:44:30

+1

'std :: vector :: emplace_back()'確實會調用默認的構造函數。一般來說'emplace_back(Args ...)'調用帶參數的構造函數'參數...' – 2015-08-13 14:00:14

+2

@Angelorf這個答案是在C++ 11發佈前寫的:)事實上C++ 11改變了'vector (5)' - 現在被指定爲就地調用默認構造函數5次,而在C++ 03中則表示您默認構建一個「X」,然後向量使用複製構造5次,並且您的默認值在之後被銷燬。 – 2015-12-21 09:30:34

11

std::vector只要求元素具有默認構造函數,如果以需要默認構造函數的方式使用它。所以這個代碼(從已刪除的答案被盜)將無法編譯,因爲X沒有一個默認的構造函數:

#include <vector> 

struct X 
{ 
    X(int) {} 
}; 

int main(void) 
{ 
    std::vector<X> x(1); // vector of length 1, second argument defaults to X() !! 
    return 0; 
} 

但是,如果你寫main喜歡這個:

int main(void) 
{ 
    std::vector<X> x; // make empty vector 
    x.push_back(X(1)); 
    return 0; 
} 

然後,它的工作原理精細。

+10

第一個版本不會編譯,因爲'std :: vector x(1)'是'std :: vector x(1,X())'的縮寫。事實上,你*誰暗中使用默認構造函數,而不是'vector'。默認參數被評估爲「在你身邊」。 – AnT 2010-03-04 05:20:29

+0

@AndreyT:偉大的一點。 – Dan 2010-03-04 05:30:45

相關問題