練習13.13的一個有意思的現象

  在作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,簡單地講就是一個動態數組,裏面有一個指針指向一片連續的內存空間,當空間不夠裝下數據時會自動申請另外一片更大的空間,而後把原有數據拷貝過去,接着釋放原來的那片空間;當釋放或者說是刪除裏面的數據時,其存儲空間並不會釋放,僅僅只是清空了裏面的數據。

相關文章
相關標籤/搜索