在作C++ Primer 5th的聯繫13.13時有一個頗有意思的現象:當一個聲明一個保存自定義類類型的vector時,若是在進行push_back操做以前這個vector的capacity和其size一致的話,則程序會向操做系統申請更多的內存以保存更多的元素。此時,整個vector會對其已經構建的元素從新所有構建一次(即調用拷貝構造函數),而後再在末尾元素以後構建新的元素。最後調用析構函數銷燬擴容以前構建的元素。數組
下面直接看程序:函數
//X結構體的定義 struct X { //默認構造函數 X() { cout << "X()" << endl; } //拷貝構造函數 X(const X&) { cout << "X(const X&)" << endl; } //拷貝賦值運算符 X& operator=(const X&) { cout << "operator=(const X&)" << endl; } //析構函數 ~X() { cout << "~X()" << endl; } }; int main(int argc, char** argv) { vector<X> vec_X; //vec_X.reserve(3); //若是不進行預留空間 //則vector進行push_back的時候 //會重複構建以前已經push_back的元素 for(unsigned i = 0; i < 5; ++i) { X temp_x; //調用默認構造函數 vec_X.push_back(temp_x); //void push_back ( const T& x ); //傳參時,調用拷貝構造函數,構造一個對象 //添加到vector的末尾 cout << vec_X.capacity() << " "; //離開for循環,temp_x被銷燬,調用析構函數 } cout << endl; return 0; }
運行的結果爲:操作系統
從運行結果能夠看出:.net
添加第一個元素時,只調用了一次X的拷貝構造函數;指針
添加第二個元素前,此時的capacity爲1,因此要爲容器擴容,擴容後爲2,添加第二個元素時,卻調用了兩次拷貝構造函數,最後調用析構函數銷燬擴容前的第一個元素;對象
添加第三個元素時,也同理,從新構造了前兩個已經構造的元素,再構造第三個元素添加至末尾;blog
添加第四個元素前,capacity爲4,足夠再添加多一個元素,則只調用了一次拷貝構造函數;內存
添加第五個元素前,capacity與size一致,須要擴容,則容器從新構造了前四個元素,而後再構造第五個元素添加至末尾,最後銷燬擴容前構造的四個元素;ci
程序結束退出,調用5次析構函數銷燬vector內的5個元素。it
另外參考了一篇文章:http://blog.csdn.net/mfcing/article/details/8746256
這篇文章詳細說明了——關於vector,簡單地講就是一個動態數組,裏面有一個指針指向一片連續的內存空間,當空間不夠裝下數據時會自動申請另外一片更大的空間,而後把原有數據拷貝過去,接着釋放原來的那片空間;當釋放或者說是刪除裏面的數據時,其存儲空間並不會釋放,僅僅只是清空了裏面的數據。