2014-01-23 46 views
10

調整矢量大小時,它會調用構造函數然後將其破壞。調整容器大小時的奇怪行爲

struct CAT 
{ 
    CAT(){cout<<"CAT()"<<endl;} 
    CAT(const CAT& c){cout<<"CAT(const CAT& c)"<<endl;}; 
    ~CAT(){cout<<"~CAT()"<<endl;}; 
}; 
int main() 
{ 
    vector<CAT> vc(6); 
    cout<<"-----------------"<<endl; 
    vc.resize(3); 
    cout<<"-----------------"<<endl; 

} 

輸出:

$./m 
CAT() 
CAT(const CAT& c) 
CAT(const CAT& c) 
CAT(const CAT& c) 
CAT(const CAT& c) 
CAT(const CAT& c) 
CAT(const CAT& c) 
~CAT() 
----------------- 
CAT()   //why resize will call constructor? 
~CAT() 
~CAT() 
~CAT() 
~CAT() 
----------------- 
~CAT() 
~CAT() 
~CAT() 

我使用Ubuntu 13.10和gcc4.8

+0

你有任何優化打開?我在VS2013中獲得的結果與您不一樣。 – Caesar

+0

@MohammedMajeed,沒有優化,這裏是我的編譯命令g ++ -Wall -o m main.cpp。使用「g ++ -Wall -O2 -o m main.cpp」會得到和我一樣的結果。 – camino

+0

@herohuyongtao它似乎創造了一個額外的,所以它不得不被破壞。 – Caesar

回答

6

這是因爲resize的可選參數。

這是我在GCC 4.8的實現:

void 
    resize(size_type __new_size, value_type __x = value_type()) 
    { 
if (__new_size > size()) 
    insert(end(), __new_size - size(), __x); 
else if (__new_size < size()) 
    _M_erase_at_end(this->_M_impl._M_start + __new_size); 
    } 

細看來value_type __x = value_type()

http://www.cplusplus.com/reference/vector/vector/resize/

void resize (size_type n, value_type val = value_type()); 
3

這可能是你的vector::resize實施裁員時會創建一個臨時默認初始化的對象,甚至,因爲它使用它在升級時初始化新的元素。

+0

這可能就是這種情況 - 否則它可能會在執行創建過程時調用6次CAT()而不是CAT(const CAT&c)。它可能會在運行構造函數時重新調整大小(int x)。 –

5

C++ 11之前,resize有一個默認的第二個參數用於初始化新元素提供值:

void resize(size_type sz, T c = T()); 

這也解釋了爲什麼你看到一個額外的對象創建和銷燬。

在一個現代化的圖書館,這被替換爲兩個重載

void resize(size_type sz); 
void resize(size_type sz, const T& c); 

,所以你不會看到任何額外的對象,除非你明確規定之一。在施工過程中,您還應該看到默認初始化,而不是複製初始化。

相關問題