1.模板:
1.函数模板
template<typename T> T:通用的数据类型, typename可用class代替
函数声明或定义
函数调用时传参类型的两种方法:
1.自动类型推导
2.显示指定类型 函数名<类型>(参数);
注意:使用模板时必须确定出通用数据类型T。并且能够推出一致的数据类型。
普通函数与模板函数的区别:
普通函数可以进行隐式类型转换
模板函数的自动类型推导不可以隐式类型转换
模板函数的显示指定类型可以隐式类型转换
普通函数与函数模板调用规则:
模板函数局限性:
利用具体化的模板可以解决自定义类型的通用化
如Person对象比较 可以写具体模板实现 template<> void compare(Person &a,Person &b){} ,当使用Person类型时调用这个函数。
2.类模板
1.类模板语法:
template<class T,...> 参数可以有多个 创建对象时指定类型 类名<参数类型> 名称;
2.类模板和函数模板的区别:
(1).类模板没有自动类型推导,只有显示指定类型
(2) 类模板可以指定模板参数列表设置默认值,如template<class T=int>,调用时可以省略。
3.类模板中的成员函数创建时机:
因为类中的成员属性未确认类型,所以成员函数在调用的时候才创建。
4.类模板对象做函数参数
三种方式如下;
(1)指定传入的类型 例如 void test(Person<stirng,int> &p);
(2)参数模板化 例如 template<class T1,class T2> void test(Person<T1,T2> &p);
(3)整个类模板化,例如 template<typename T> void test(T &p);
5.类模板和继承
(1)如果父类是类模板,则其子类必须指明父类中的类型
子类格式: class 子类:public 父类<指定父类参数类型>
(2) 如果想要使得指定父类参数类型可以改变,则子类也需要写成类模板形式
格式:template<class T1,class T2> class 子类:public 父类<T2>{T1 obj};
T2指的是指定父类中的参数类型。
6.类模板中的成员函数类外实现
格式 : template<class T1,class T2 ... >
void Person<T1,T2..>test(T1 a,T2 b){}
7.类模板中成员函数分文件编写问题及解决方式
如果在头文件中写类模板,并在源文件中写成员函数的实现,会出现编译时链接不到的问题,如果主文件中包含头文件,但由于头文件中的类模板中的成员函数此时还未创建(因为类模板中的成员函数是在调用时才创建),因此找不到源文件中的成员函数实现。
解决方式:将类模板和成员函数实现编写到一个文件中,使用.hpp作后缀名。这通常是类模板文件的后缀名。
8.类模板与友元
当使用友元函数时,建议使用类内友元,类外实现过于复杂。
2 STL
stl六大组件:容器、算法、迭代器、仿函数、连接器、空间配置器。
1.vector
动态开辟空间。
迭代器:begin()指向第一个元素, end()指向最后一个元素的下一个位置
遍历:使用迭代器、使用内置算法for_each()
(1)构造函数
1.默认无参构造vector <类型> v
2.区间构造 vector<类型> v(begin(),end())
3.vector<类型> v(个数,数值)
4.拷贝构造vector <类型> v(v1);
(2)赋值操作
1.重载的=运算符
2.assign(begin,end)
3 assign(n,elem)
(3)容量和大小
判断容器为空:empty
返回元素个数:size
返回容器容量:capacity
重新指定大小: resize
(3)插入和删除
插入:尾插push_back(),insert(迭代器,elem),insert(迭代器,n,elem)
删除:尾删pop_back(), erase(迭代器) ,erase(begin,end) , clear()清空
(4)存取元素
[ ]、at 、front 、back
(5)互换容器
swap(),可以交换两个容器内的元素
用途:可以收缩内存空间
vector<int> v1;
for(int i=0;i<100000;i++)
v1.push_back(i);
//由于v1的容量要比size大
//加入resize变小
v1.resize(3) //此时容量不变,大小变为3,所以浪费了很多内存空间
//
vector<int>(v1).swap(v1);//使用匿名对象时将v1的大小拷贝,然后利用swap函数进行交换
(6) 预留空间
reserve()提前开辟内存空间
2.string容器
(1)string的构造函数
无参构造:创建一个空字符串 string str;
使用一个字符串初始化:string str(字符串);
拷贝构造 : string str2(str1);
使用n个字符初始化: string str(n,c);
(2)字符串赋值操作
使用=号:
使用assign成员函数: 区别:assign(const char *,n)可以把前n个字符赋值
(3)字符串拼接
使用+=号:可以拼接字符常量、字符、其他string字符串
使用append:拼接字符串时可以指定长度如 append(const char*,n);append(string s,pos,n); 从第几个位置开始拼接。
(4)字符串查找和替换
int find(const string& str, int pos = 0) const; //查找str第一次出现位置,从pos开始查找,未找到返回-1
int find(const char* s, int pos = 0) const; //查找s第一次出现位置,从pos开始查找
int find(const char* s, int pos, int n) const; //从pos位置查找s的前n个字符第一次位置
int find(const char c, int pos = 0) const; //查找字符c第一次出现位置
int rfind(const string& str, int pos = npos) const; //查找str最后一次位置,从pos开始查找
int rfind(const char* s, int pos = npos) const; //查找s最后一次出现位置,从pos开始查找
int rfind(const char* s, int pos, int n) const; //从pos查找s的前n个字符最后一次位置
int rfind(const char c, int pos = 0) const; //查找字符c最后一次出现位置
string& replace(int pos, int n, const string& str); //替换从pos开始n个字符为字符串str
string& replace(int pos, int n,const char* s); //替换从pos开始的n个字符为字符串s
(5)字符串比较:compare() 相等返回0 大于返回1 小于返回-1
(6)字符存取: 1.[]访问下标 2.at(下标)
(7)字符串插入和删除
插入:insert(起始位置,str)
删除:erase (pos,n)
(8) 字符串截取 substr(pos,n)
3.deque容器 (双端数组)
deque容器是由一个中控器控制,通过创建缓冲区存储,存取效率较低。
小技巧:如果使传入的容器不可修改加入const后 在遍历时使用const_iterator迭代器
1.构造函数和vector基本一致
2.赋值操作参考vector
3.大小操作
与vector的区别,没有capacity操作,因为他没有容量的概念
判断空:empty
返回大小:size
指定大小:resize
4.插入和 删除
尾部和头部:
popback pop_front push_back push_front
插入: insert (pos,begin,end)(pos,elem) (pos,n,elem)
删除:erase(begin,end)erase(pos)、clear
number = (rand()%(maxValue - minValue +1)) + minValue;取给定范围内的随机数函数
4.Stack容器
1.构造函数
stack<T> stk;
stack<T> stk(const stack &stk) 拷贝构造函数
2.赋值操作 : =
3.入栈出栈
pop() 、push()、top()返回栈顶元素
empty:是否为空 size:大小
5.queue容器
1.构造函数
queue<T> stk;
queue<T> stk(const queue&stk) 拷贝构造函数
2.赋值操作 : =
3.入栈出栈
pop()出队 、push()入队、back()返回队尾元素,front()返回对头元素
empty:是否为空 size:大小
5.List容器
list 是一个双向循环链表,它的存储空间不是连续的,不支持随机访问。
重要性质,list中插入或删除一个元素,原始的迭代器不会失效,但vector不成立
迭代器为双向迭代器,只支持前移和后移。
1.构造函数
(1) 默认无参构造 List<T> list;
(2)区间构造 List<T> list(begin,end)
(3)List<T> list(n,elem)
(4) 拷贝构造const (const list &list)
2.赋值和交换
1.重载等号运算符
2.assign()
3交换,swap
3.大小操作
empty、size、resize
3.插入和删除
- push_back(elem);//在容器尾部加入一个元素
- pop_back();//删除容器中最后一个元素
- push_front(elem);//在容器开头插入一个元素
- pop_front();//从容器开头移除第一个元素
- insert(pos,elem);//在pos位置插elem元素的拷贝,返回新数据的位置。
- insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。
- insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值。
- clear();//移除容器的所有数据
- erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
- erase(pos);//删除pos位置的数据,返回下一个数据的位置。
- remove(elem);//删除容器中所有与elem值匹配的元素。
4.数据存取
只能使用front和back
5.排序和反转
反转:reverse
排序:sort() 只能使用list内置的sort函数,因为sort算法只支持随机访问的容器,而list不支持随机访问。sort()降序只需写一个函数将函数名作为参数。
5. set容器
set容器对插入的数据自动排序,并且无重复元素。插入数据时只能用insert。
1.构造和赋值
1.构造:set<T> set set<T> set(拷贝构造);
2.赋值:重载等号
2.大小和交换
empy:判断是否为空
size:元素个数
swap:交换容器
3.插入和删除
插入:insert
删除:clear 、erase(pos)、erase(begin,end)、erase(elem):按元素删除.
4.查找和统计
find()找到返回迭代器所在位置,否则返回end();
count() 统计数字出现次数
5.mutiset和set
mutiset可以插入重复元素,set插入元素操作返回的是一个pair,返回插入是否成功
6.内置类型指定排序规则
class Mycompare
{
public:
bool operator()(int a,int b)
{
return a>b
}
};
set<type,class>
7.自定义类型指定排序规则
因为自定义类型不知道按照什么关键字排序,因此存放自定义类型数据时要指定排序规则;
6.pair对组
pair<type,type> p()
7.map容器
map中所有元素都是pair,且容器会根据键值自动排序,key不允许有重复元素,
mutimap允许有重复key
1.构造函数 map<type,type> m;map<type,type> m(拷贝构造);
2.赋值:重载等号运算符
1.大小和交换
empty、size、swap
2.插入和删除操作
插入:insert
(1) insert(pair<type,type>())
(2) insert(make_pair()) 建议使用
(3)[]方式,不建议使用,但可以使用【】访问元素
删除:erase(pos),erase(begin,end)erase(关键字),clear();
3.查找和统计
find(key)返回迭代器 ,count(key)
4.排序 使用仿函数实现
8.函数对象
函数对象就是一个重载()操作符的类,其对象成为函数对象
函数对象使用()重载符时,相当于调用函数,因此成为仿函数;
函数对象的使用
1.函数对象在调用时,可以有参数,有返回值。
2.函数对象可以有自己的状态,例如记录函数调用次数
3.函数对象可以作为参数传递
谓词
谓词是返回bool类型的仿函数,一个参数的称为一元谓词,两个称为二元谓词
一元谓词:
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
class compare
{
public:
bool operator()(int v)
{
return v>5;
}
};
void main()
{
vector<int> v;
for(int i=0;i<10;i++)
v.push_back(i);
vector<int>::iterator it=find_if(v.begin(),v.end(),compare()); //参数:起始位置,终止位置,pred谓词
cout<<(*it)<<endl;
system("pause");
}
内置函数对象-算术仿函数
使用内置仿函数,需要引入头文件#include<functional>
实现四则运算,negate是一元运算,其他为二元
template<class T> T plus<T>
//加法仿函数template<class T> T minus<T>
//减法仿函数template<class T> T multiplies<T>
//乘法仿函数template<class T> T divides<T>
//除法仿函数template<class T> T modulus<T>
//取模仿函数template<class T> T negate<T>
//取反仿函数
内置函数对象-关系仿函数
template<class T> bool equal_to<T>
//等于template<class T> bool not_equal_to<T>
//不等于template<class T> bool greater<T>
//大于template<class T> bool greater_equal<T>
//大于等于template<class T> bool less<T>
//小于template<class T> bool less_equal<T>
//小于等于
内置函数对象-逻辑仿函数
template<class T> bool logical_and<T>
//逻辑与template<class T> bool logical_or<T>
//逻辑或template<class T> bool logical_not<T>
//逻辑非