C++ 学习笔记----模版与标准模板库篇
(一)模板
1、模板的基本知识:
(1)定义模板:
1 template <class T> 2 class Array { 3 //...... 4 };
(2)实例:
1 template <class T> 2 class Array { 3 public : 4 T& operator[](int); 5 const T& operator[](int) const; 6 Array(int); 7 ~Array(); 8 int get_size() const {return size;} 9 private : 10 T* a; 11 int size; 12 Array(); 13 T dummy_val; 14 }; 15 16 template <class T> 17 T& Array<T>::operator[](int i){ 18 if(i<0 || i>=size) 19 { 20 cerr<<"index "<<i<<" out of bounds: "; 21 return dummy_val; 22 } 23 return a[i]; 24 } 25 template <class T> 26 const T& Array<T>::operator[](int i) const { 27 if(i<0 || i>=size) 28 { 29 cerr<<"index "<<i<<" out of bounds: "; 30 return dummy_val; 31 } 32 return a[i]; 33 } 34 template <class T> 35 Array<T>::Array(int s) { 36 a = new T[size = s]; 37 } 38 template <class T> 39 Array<T>::~Array(){ 40 delete[] a; 41 }
(3)模板的函数式参数:
1 template <class T, int X, float Y> 2 class Sample { 3 //...... 4 };
(二)标准模板库(STL:Standard Template Library)
1、基本知识:
(1)容器:对象的集合;包括:vector、stack、queue、list、set、map等;可以理解为数据结构;
(2)算法:对容器进行处理的函数;可以理解为处理数据结构的函数;
(3)迭代器:访问容器中对象的一种机制,一次访问一个对象;
2、容器:
(1)容器分为两组:序列式容器(vector、deque、list)和关联式容器(set、multiset、map、multimap);
list | 序列式 | 双向链表 |
vector | 序列式 | 可伸缩数组 |
deque | 序列式 | 两端进行有效插入和删除的数组 |
set | 关联式 | 不含重复键的集合 |
multiset | 关联式 | 允许重复的set |
map | 关联式 | 用键访问的不含重复的集合 |
multimap | 关联式 | 允许重复键的map |
(2)vector:是一个双向链表;插入和删除操作在尾部进行效率比较高;
1 #include <iostream> 2 #include <vector> 3 4 using namespace std; 5 6 int main(int argc, char argv[]) 7 { 8 int i; 9 vector<int> nums; 10 nums.insert(nums.begin(), -999); 11 nums.insert(nums.begin(), 14); 12 nums.insert(nums.end(), 57); 13 for(i = 0;i<nums.size(); i++) //size返回vector的大小 14 cout<<nums[i]<<endl; //可以使用 [] 访问其中的元素,因为vector重载了 [] 15 nums.erase(nums.begin()); 16 nums.erase(nums.begin()); 17 for(i = 0;i<nums.size(); i++) 18 cout<<nums[i]<<endl; 19 system("PAUSE"); 20 return 0; 21 }
说明:vector支持在两端插入元素,并提供begin和end成员函数,分别用来访问头部和尾部元素,两个函数都返回一个可随机访问的迭代器;
begin返回的迭代器:容器不为空,指向容器的第一个元素,容器为空,指向容器尾部之后的位置;
end返回的迭代器:仅指向容器尾部之后的位置;
(3)deque:不管是在头部还是在尾部操作,效率是固定的;其他和vector类似;
(4)list:注意它的实现是“双向链表”;例如:
1 #include <iostream> 2 #include <list> 3 #include <string> 4 5 using namespace std; 6 7 void dump(list<string>& l) 8 { 9 //list<const string>::const_iterator it;// list iterator 10 list <string>::iterator it; 11 it = l.begin(); 12 while(it != l.end()) 13 { 14 cout<<*it<<endl; 15 it++; 16 } 17 } 18 19 int main(int argc, char argv[]) 20 { 21 list<string> names; 22 names.insert(names.begin(), "Hello"); 23 names.insert(names.begin(), "World"); 24 names.insert(names.end(), "!"); 25 dump(names); 26 names.reverse(); 27 cout<<endl; 28 dump(names); 29 system("PAUSE"); 30 return 0; 31 }
(5)vector、deque、list的比较:
操作 | vector | deque | list |
在头部插入或删除元素 | 线性 | 恒定 | 恒定 |
在尾部插入或删除元素 | 恒定 | 恒定 | 恒定 |
在中间插入或删除元素 | 线性 | 线性 | 恒定 |
访问头部的元素 | 恒定 | 恒定 | 恒定 |
访问尾部的元素 | 恒定 | 恒定 | 恒定 |
访问中间的元素 | 恒定 | 恒定 | 线性 |
(6)基本关联式容器:set、multiset、map、multimap
set是一种集合,其中可包含0个或多个不重复和不排序的元素,这些元素被称为键值。
map也是一种集合,其中可包含0个或多个不重复和不排序的元素对,一个元素是不重复的键值,另一个是与键相关联的值。
multiset是容许有重复键值的set;
multimap是容许有重复键值的map;
(7)容器适配器:是基本容器的衍生物,并利用基本容器来实现其特定的功能;
种类:stack、queue、priority_queue;
stack适用于LIFO(后进先出)列表;
queue适用于FIFO(先进先出)列表;
priority_queue用于创建带优先级的队列,其元素以某种优先顺序进行删除;
(8)其它容器:string、bitset;
3、STL算法:排序、搜索、数值处理、集合运算、拷贝等
1 #include <iostream> 2 #include <vector> 3 #include <string> 4 #include <algorithm> 5 6 using namespace std; 7 8 void dump(int i) 9 { 10 cout<<i<<endl; 11 } 12 bool odd(int i) 13 { 14 return i%2 != 0; 15 } 16 bool cmp(const int& i1,const int& i2) 17 { 18 return i1 > i2; 19 } 20 21 int main(int argc, char argv[]) 22 { 23 vector<int> v(10); 24 generate(v.begin(), v.end(), rand); 25 26 replace_if(v.begin(), v.end(), odd, 0); 27 28 sort(v.begin(), v.end(), cmp); 29 30 for_each(v.begin(), v.end(), dump); 31 32 system("PAUSE"); 33 return 0; 34 }
4、其它STL组件:函数对象、函数适配器、STL allocator;
1 //////////////////////////////////////////////////////////////////////////////// 2 //C++学习笔记 3 ////////////////////////////////////////////////////////////////////////////////