一、模板
(一)函数模板
1.定义:
函数模板名(形式参数表){
//函数体
}
2.赋默认值:P13啥意思?
(二)类模板
1.定义:
class 类模板名 {
//类定义体
};
2.实例化:
3.类模板的成员函数定义
//放在类模板的定义体中,与类的成员函数定义格式相同;或在全局区域中定义
template<类型形式参数表>
函数返回值类型 类模板名<类型名表>::成员函数名(形参表){
//函数体}
#include <iostream>
using namespace std;
//定义类模板AClass,包括两个成员函数
template<class T, int N>
class AClass {
private:
T values[N];
public:
//成员函数的模板参数(类内定义)
//template<class T, int N>
void Set(int x) {
for(int i = 0; i < N; i++) {
values[i] = x + i;
}
}
void Show();
};
//成员函数的模板参数(类外定义)
template<class T, int N>
void AClass<T, N>::Show() {
for(int i = 0; i < N; i++)
cout<<"values["<<i+1<<"]="<<values[i]<<endl;
}
int main() {
AClass<int, 5> a1;//模板类实例化得到对象
a1.Set(2);
a1.Show();
AClass<double, 10> a2;
a2.Set(10);
a2.Show();
return 0;
}
//输出
//values[1]=2//values[2]=3//values[3]=4//values[4]=5//values[5]=6//values[1]=10//values[2]=11//values[3]=12//values[4]=13//values[5]=14//values[6]=15//values[7]=16//values[8]=17//values[9]=18//values[10]=19
- 普通类的成员函数,也可定义为类模板
- 类模板的成员函数,也可有额外的模板参数
class normal_ class {
public:
int value;
//类内定义
template<typename T>
void set(T const& v) {
value = int(v);
}
template<typename T>
T get();
};
//类外定义
template<typename T>
T normal_class::get() {
return T(value);
}
template<typename T0>
class A {
public:
T0 value;
//类内定义
template<typename T1>
void set(T1 const& v) {
value = T0(v);
}
template<typename T1>
T1 get();
};
//类外定义
T1 A::get() {
return T1(value);
}
4.模板参数是另一个类模板
template<typename T, template<typename TT0, typename TT1> class A>
struct Foo{
A<T, T>bar;
};
5.模板特化
- 对函数模板,如果有多个模板参数,则特化时必须提供所有参数的特例类型,不能部分特化。
template<>char* sum(char *a, char *b){}或template<><char*> sum(char *a, char *b){} - 对于类模板,允许部分特化,即部分限制模板的通用性。
template<class T1>class A<T1, int>{...}若指定所有类型,则<>内为空template<> class A<int, int>{...}
二、迭代器
1.内敛函数
inline int min(int a, int b){return (a>b)?a:b;}- 避免函数调用开销空间换时间
- 在类定义体内定义的函数缺省为内联函数
2.变与不变
- 不变:算法/抽象结构的接口与实现;“数据”的访问接口不变(迭代器);“数据”的可用操作(操作符重载)
- 变:“数据”的组织形式;“数据”的类型(值域、存储、操作实现)
三、STL标准模板库Standard Template Library
(一)容器
1.顺序容器
- 将元素按照严格的线性形式组织起来
- 对元素的访问可以采用顺序方式或随机方式
- 包括vector、list、deque
2.关联容器
- 将元素按照非线性形式组织起来
- 根据一组索引来快速的访问元素
- 包括set、multiset、map、multimap
3.vector
- 内部用动态数组来存放元素
- 长度可变是一个类模板,元素类型任意
常用成员函数:
vector()创建一个长度为0的空向量
vector(size_type n, const T &val=T())创建一个长度为n的向量,每个元素的初始值为val
size_type size()const返回当前容器中元素的个数
size_type capacity()const返回容器当前可存放元素的个数
bool empty()如果容器为空则返回true,否则返回false
void push_back(const T &x)在容器末尾添加元素x
void clear()删除容器中的全部元素
void reserve(size_type n)重新分配内容,使其可存放n个元素
#include <iostream>
#include<vector>
using namespace std;
int main() {
int i;
vector<int> v1;
for(i = 0 ; i < 3; i++)
v1.push_back(i+1);
v1.reserve(5);
for(i = 0 ; i < 5; i++)
cout<<v1[i]<<endl;
cout<<endl;
vector<double> v2(5, 7.8);
for(i = 0 ; i < v2.size(); i++)
cout<<v2[i]<<endl;
return 0;
}
(二)迭代器
- 是一种通用指针,可以方便对容器进行定位和操作
- 每个容器都有自己的迭代器
vector的与迭代器相关的常用成员函数:
iterator insert(iterator it, const T &x)在迭代器it所指的位置前插入元素x
iterator erase(iterator it)删除迭代器it指向的元素
iterator begin()返回指向第一个元素的迭代器
iterator end()返回指向最后一个元素后一个位置的选代器
#include <iostream>
#include<vector>
using namespace std;
int main() {
vector<double> v1(5, 7.8);
vector<double>::iterator it1;
for(it1 = v1.begin(); it1 < v1.end(); it1++)
cout<<*it1<<endl;
vector<char> v2;
v2.push_back('b');
vector<char>::iterator it2;
it2 = v2.begin();
v2.insert(it2, 'a');
it2 = v2.end();
v2.insert(it2, 'c');
for(it2 = v2.begin(); it2 < v2.end(); it2++)
cout<<*it2<<endl;
return 0;
}
//output:
//7.8
//7.8
//7.8
//7.8
//7.8
//a
//b
//c
(三)算法
sort(v.begin(), v.end());