STL中迭代器的兩種模式,你知道嗎?(讀/寫模式和只讀模式)

一、iterator 和 const_iterator

STL中的迭代器是一種智能指針,不同的容器使用不同類型的迭代器。迭代器的主要目的就是幫助我們對相應容器進行遍歷操作,以一個對象的形式表現出容器中元素的具體位置。

迭代器具有遍歷複雜數據結構的能力,其內部的運作機制取決於具體的數據結構形式,所以每一種容器都會有自己迭代器實現。

本文想要討論的是迭代器實現的兩種模式,可以在不同的讀/寫情境下供我們選擇使用。STL中所有的容器都實現了這兩種迭代器類型。它們分別是:

(1)container::iterator : 以 讀/寫模式 訪問元素
(2)container::const_iterator: 以 只讀模式 訪問元素

二、使用const_iterator遍歷list容器

以下以list容器爲例子,分別使用兩種迭代器對容器元素進行遍歷、讀寫操作,請看具體實例:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <list>
using namespace std;

int main()
{
	list<int> s{ 1,2,3,4,5,6,7,8 };
	
	// 迭代器:讀/寫模式,此迭代器可以對容器內元素進行讀和寫操作
	list<int>::iterator rw_iter;
	for (rw_iter = s.begin(); rw_iter != s.end(); ++rw_iter)
	{
		*rw_iter *= 2; // 寫操作,每個變量乘以2
		cout << *rw_iter << " "; // 讀操作
	}
	cout << endl;

	// 迭代器:只讀模式,此迭代器只能對元素進行讀操作
	list<int>::const_iterator r_iter;
	for (r_iter = s.begin(); r_iter != s.end(); ++r_iter)
	{
		//*r_iter *= 2; // error 表達式必須是可被修改的左值
		cout << *r_iter << " ";
	}
	cout << endl;

	return 0;
}

可以看到使用const_iterator的迭代器類型後,是無法對數據進行寫操作的。這就提供了對數據的保護,當我們需要對數據進行只讀操作時,便可以定義此類迭代器進行操作。另外,也可以根據具體情境,定義需要的迭代器類型。

三、cbegin()、cend() 與 Range-Based for 循環

此外,C++11之後,容器提供了cbegin()cend(),它們表示const_iterator,因此,當我們在遍歷一個容器的時候,如果不允許修改其值,我們可以使用這樣的方式:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
using namespace std;

int main()
{
	vector<int> v{ 1,2,3,4,5 };
	for (auto iter = v.cbegin(); iter != v.cend(); ++iter)
	{
		cout << *iter << " "; // 1 2 3 4 5
	}
	return 0;
}

或者我們可以使用C++11提供的range-based for循環來對容器進行遍歷,這是一個更便捷的遍歷接口,我們可以聲明對象爲const reference,來避免修改和拷貝,從而提高效率。使用方式如下:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
using namespace std;

int main()
{
	vector<int> v{ 1,2,3,4,5 };
	// const auto& : 避免數值被修改、使用引用避免數據拷貝
	for (const auto& elem : v) 
	{
		cout << elem << " "; // 1 2 3 4 5
	}
	return 0;
}

再次強調,當我們使用以上形式的for循環時,如果不會對數據做出修改,我們應該聲明其類型爲引用(reference)const(常量),這樣就避免調用元素的copy構造函數和析構函數,在數據類型複雜的情況下,能節省開銷。

謝謝閱讀。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章