C++ vector容器的swap方法(容器互換)

對的時間點發表於2019-11-21

swap方法可以交換兩容器的內容。

int main()
{
	vector<int> v1;
	v1.push_back(10);
	v1.push_back(20);
	vector<int> v2;
	v2.push_back(30);
	
	//printVector是自己編寫用於遍歷輸出vector容器的函式
	printVector(v1);
	printVector(v2);
	
	v1.swap(v2);
	
	printVector(v1);
	printVector(v2);
	system("pause");
	return 0;
}

輸出結果為:
在這裡插入圖片描述
可以看到,兩次輸出的結果不一樣。兩容器的內容被交換了。

但,這有什麼用呢??

答案是可以用來收縮記憶體空間

我們都知道,vector容器和陣列類似,但是又有區別。

vector容器可以動態擴充套件。而陣列不能擴充套件,大小被指定後就不能再更改了。至少再使用上不能直接增加了。

那麼為什麼vector容器可以動態擴充套件呢??很簡單,當vector容器滿了,就再重新建一個vector容器,然後將原vector容器的內容拷貝至新容器。

問題來了,容器滿後,是我每新增一個資料,就需要重新建立容器擴充一次嗎??答案當然是否定的,如下圖,原容器容量為5,裡面儲存了5個資料。當我們再向裡面新增資料的時候,因為容器已滿,所以容器會動態擴充,但是會多擴充一些空位,以防下次再次增加資料。當然具體有多少個空位我們不需要關心。
在這裡插入圖片描述
這樣做時有好處的,因為當資料量比較少的時候,將舊容器拷貝至新容器可能會很快,當時當資料量比較大的時候呢??這種擴充很浪費資源。這可能算是利用空間換時間的例子吧。

這樣還雖然有好處,但是也有弊端。舉個例子,如下圖:
在這裡插入圖片描述
當我們將一個容量為一百萬的容器,使用 resize(5) 函式重新指定大小為5的時候,它並不是向上圖一樣,就剩下5個空間,將其餘空間釋放掉,而是下圖這種狀態:
在這裡插入圖片描述
所有空間都還在。
我們看一下這個函式名,resize()
size()函式 作用是返回vector容器的大小(也就是實際資料量)
capacity() 作用是返回vector容器的容量大小(也就是空間的多少)

對比之下我們應該猜的出,resize()做的操作大概是直接修改了容量大小,讓我不能訪問後面的資料,而不是釋放空間。

這就是問題所在,重新指定大小後,這麼大的空間就浪費掉了。

而swap()可以解決這個問題。

用法如下:

vector<int>(v).swap(v);	//v是容器名

也就是說通過該語句,可以將v中空閒的空間釋放掉。

這條語句可以分為兩個部分:
vector(v).swap(v) 兩部分

首先看第一部分,vector(v)
首先,這條語句,通過 拷貝建構函式 建立了一個 匿名物件 ,這個匿名物件擁有v的全部資料,但是,沒有空閒的空間,也就是說,這個匿名物件的容量和儲存的資料量是相等的。如下圖:
在這裡插入圖片描述
程式碼測試如下:

vector<int> v1;
for (int i = 0; i < 100000; i++)
{
	v1.push_back(i);
}
cout << "v1的容量:" << v1.capacity() << endl;
cout << "v1的大小:" << v1.size() << endl;		

v1.resize(3);
cout << "v1的容量:" << v1.capacity() << endl;
cout << "v1的大小:" << v1.size() << endl;	

vector<int>v2(v1);

cout << "v2的容量:" << v2.capacity() << endl;
cout << "v2的大小:" << v2.size() << endl;

結果如下:
在這裡插入圖片描述
所以經過 vector(v) 建立出來的匿名物件是沒有空閒空間的,此時,通過 .swap(v) 呼叫該匿名類的swap()方法,交換v與匿名類的內容,結果如下:
在這裡插入圖片描述
最後,該行語句指向完畢,匿名類被析構,空間被釋放。

最終結果就是,原容器中的空位被釋放

相關文章