Android NDK開發之旅26 C++ STL

kpioneer123發表於2018-01-19

###1.1 什麼是STL?

Android NDK開發之旅26  C++  STL

STL(Standard Template Library),即標準模板庫,是一個具有工業強度的,高效的C++程式庫。它被容納於C++標準程式庫(C++ Standard Library)中,是ANSI/ISO C++標準中最新的也是極具革命性的一部分。該庫包含了諸多在電腦科學領域裡所常用的基本資料結構和基本演算法。為廣大C++程式設計師們提供了一個可擴充套件的應用框架,高度體現了軟體的可複用性。 STL的一個重要特點是資料結構和演算法的分離。儘管這是個簡單的概念,但這種分離確實使得STL變得非常通用。例如,由於STL的sort()函式是完全通用的,你可以用它來操作幾乎任何資料集合,包括連結串列,容器和陣列; STL另一個重要特性是它不是物件導向的。為了具有足夠通用性,STL主要依賴於模板而不是封裝,繼承和虛擬函式(多型性)——OOP的三個要素。你在STL中找不到任何明顯的類繼承關係。這好像是一種倒退,但這正好是使得STL的元件具有廣泛通用性的底層特徵。另外,由於STL是基於模板,行內函數的使用使得生成的程式碼短小高效; 從邏輯層次來看,在STL中體現了泛型化程式設計的思想,引入了諸多新的名詞,比如像需求(requirements)概念(concept)模型(model)容器(container)演算法(algorithmn)迭代子(iterator)等。與OOP(object-oriented programming)*中的多型(polymorphism)**一樣,泛型也是一種軟體的複用技術;從實現層次看,整個STL是以一種型別引數化的方式實現的,這種方式基於一個在早先C++標準中沒有出現的語言特性--模板(template)

###1.2 STL內容介紹

元件 描述
容器(Containers) 容器是用來管理某一類物件的集合。C++ 提供了各種不同型別的容器,
比如 deque、list、vector、map 等。
演算法(Algorithms) 演算法作用於容器。它們提供了執行各種操作的方式,包括對容器內容執行初始化、
排序、搜尋和轉換等操作。
迭代器(iterators) 迭代器用於遍歷物件集合的元素。這些集合可能是容器,也可能是容器的子集。

####1.2.1 容器

STL中的容器有佇列容器和關聯容器,容器介面卡(congtainer adapters:stack,queue,priority queue),位集(bit_set),串包(string_package)等等。 (1)序列式容器(Sequence containers),每個元素都有固定位置--取決於插入時機和地點,和元素值無關,vector、deque、list;

(2)關聯式容器(Associated containers),元素位置取決於特定的排序準則,和插入順序無關,set、multiset、map、multimap;

容器類自動申請和釋放記憶體,無需new和delete操作。vector基於模板實現,需包含標頭檔案vector。 ######示例如下:

#include <iostream>
#include <vector>
using namespace std;
void main() {

	//1.定義和初始化  
	vector<int> vec1;    //預設初始化,vec1為空  
	vector<int> vec2(vec1);  //使用vec1初始化vec2  
	vector<int> vec3(vec1.begin(), vec1.end());//使用vec1初始化vec2  
	vector<int> vec4(10);    //10個值為的元素  
	vector<int> vec5(10, 4);  //10個值為的元素  

	//2.常用操作方法  
	vec1.push_back(100);            //新增元素  
	int size = vec1.size();         //元素個數  
	bool isEmpty = vec1.empty();    //判斷是否為空  
	cout << vec1[0] << endl;        //取得第一個元素  
	vec1.insert(vec1.end(), 5, 3);    //從vec1.back位置插入個值為的元素  
	vec1.pop_back();              //刪除末尾元素  
	vec1.erase(vec1.begin(), vec1.end());//刪除之間的元素,其他元素前移  
	cout << (vec1 == vec2) ? true : false;  //判斷是否相等==、!=、>=、<=...  
	vector<int>::iterator iter = vec1.begin();    //獲取迭代器首地址  
	vec1.clear();                 //清空元素  

	//3.遍歷  
	//下標法  
	int length = vec1.size();
	for (int i = 0; i < length; i++)
	{
		cout << vec1[i];
	}
	cout << endl << endl;
	//迭代器法  
	vector<int>::const_iterator iterator = vec1.begin();
	for (; iterator != vec1.end(); iterator++)
	{
		cout << *iterator;
	}
	system("pause");
}

結果輸出:
100
1
複製程式碼

####1.2.2 迭代器

Iterator(迭代器)模式又稱Cursor(遊標)模式,用於提供一種方法順序訪問一個聚合物件中各個元素, 而又不需暴露該物件的內部表示。或者這樣說可能更容易理解:Iterator模式是運用於聚合物件的一種模式,通過運用該模式,使得我們可以在不知道物件內部表示的情況下,按照一定順序(由iterator提供的方法)訪問聚合物件中的各個元素。 迭代器的作用:能夠讓迭代器與演算法不干擾的相互發展,最後又能無間隙的粘合起來,過載了*,++,==,!=,=運算子。用以操作複雜的資料結構,容器提供迭代器,演算法使用迭代器;常見的一些迭代器型別:iterator、const_iterator、reverse_iterator和const_reverse_iterator。

######示例如下:


#include <iostream>  
#include <vector>  
using namespace std;
int main()
{
	vector<int> v;
	v.push_back(3);  //陣列尾部插入3  
	v.push_back(2);
	v.push_back(1);
	v.push_back(0);
	cout << " 下標 " << v[3] << endl;
	cout << " 迭代器 " << endl;
	for (vector<int>::iterator i = v.begin(); i != v.end(); ++i)
	{
		cout << *i << " ";
	}
	cout << endl;
	//在第一個元素之前插入111  insert begin+n是在第n個元素之前插入  
	v.insert(v.begin(), 111);
	//在最後一個元素之後插入222 insert end + n 是在n個元素之後插入  
	v.insert(v.end(), 222);
	for (vector<int>::iterator i = v.begin(); i != v.end(); ++i)
	{
		cout << *i << " ";
	}
	cout << endl;

	vector<int> arr(10);
	for (int i = 0; i < 10; i++)
	{
		arr[i] = i;
	}
	for (vector<int>::iterator i = arr.begin(); i != arr.end(); ++i)
	{
		cout << *i << " ";
	}
	cout << endl;
	//刪除 同insert  
	arr.erase(arr.begin());
	for (vector<int>::iterator i = arr.begin(); i != arr.end(); ++i)
	{
		cout << *i << " ";
	}
	cout << endl;
	arr.erase(arr.begin(), arr.begin() + 5);
	for (vector<int>::iterator i = arr.begin(); i != arr.end(); ++i)
	{
		cout << *i << " ";
	}
	cout << endl;
	system("pause");
	return 0;
}

結果輸出:
 下標 0
 迭代器
3 2 1 0
111 3 2 1 0 222
0 1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
6 7 8 9
複製程式碼

####1.2.3、演算法

函式庫對資料型別的選擇對其可重用性起著至關重要的作用。舉例來說,一個求方根的函式,在使用浮點數作為其引數型別的情況下的可重用性肯定比使用整型作為它的引數類性要高。而C++通過模板的機制允許推遲對某些型別的選擇,直到真正想使用模板或者說對模板進行特化的時候,STL就利用了這一點提供了相當多的有用演算法。它是在一個有效的框架中完成這些演算法的——你可以將所有的型別劃分為少數的幾類,然後就可以在模版的引數中使用一種型別替換掉同一種類中的其他型別。 STL提供了大約100個實現演算法的模版函式,比如演算法for_each將為指定序列中的每一個元素呼叫指定的函式,stable_sort以你所指定的規則對序列進行穩定性排序等等。只要我們熟悉了STL之後,許多程式碼可以被大大的化簡,只需要通過呼叫一兩個演算法模板,就可以完成所需要的功能並大大地提升效率。 演算法部分主要由標頭檔案,和組成。 是所有STL標頭檔案中最大的一個(儘管它很好理解),它是由一大堆模版函式組成的,可以認為每個函式在很大程度上都是獨立的,其中常用到的功能範圍涉及到比較、交換、查詢、遍歷操作、複製、修改、移除、反轉、排序、合併等等。 體積很小,只包括幾個在序列上面進行簡單數學運算的模板函式,包括加法和乘法在序列上的一些操作。 中則定義了一些模板類,用以宣告函式物件。

######陣列反轉 ( reverse)示例如下:

#include<iostream>  
#include<vector>  
#include<algorithm>  
using namespace std;  
int main()  
{  
    vector<int> v;  
    for(int i = 0; i < 10; ++i)  
    {  
        v.push_back(i);  
    }  
    for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)  
    {  
        cout << *it << " ";  
    }  
    cout << endl;  
    reverse(v.begin(),v.end());  
    for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)  
    {  
        cout << *it << " ";  
    }  
    cout << endl;  
    return 0;  
}

結果輸出:
0 1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1 0
複製程式碼

####總結 #####C++ 中STL 與Java中某些現有概念挺類似,例子看起來很簡單,實際上C++ 中STL中的知識內容其實挺晦澀難懂,很多內容我都省略了。之所以要學它,是因為有大量的開源庫,如ffmpeg使用了它。

#####參考: www.cnblogs.com/jchm/p/5443… blog.csdn.net/piaoxuezhon…

相關文章