c++模版

模版:模版使程序员能够快速建立具有类型安全的类库集合和函数集合,它的实现,方便了大规模的软件开发。

一般形式:

template<类型形式参数表>

返回类型 FunctionName(形式参数表)

//函数定义体

绝对值的模版:

#include<iostream>
using namespace std;
<span style="background-color: rgb(255, 204, 255);">template<typename T>
T abs(T x)
{
	return x<0?-x:x;
}</span>
int main()
{
	int a=-5;
	int b=6;
	cout<<abs(a)<<endl;
	cout<<abs(b)<<endl;
	return 0;
}

模版作用:

使用类模版使用户为类声明一种模式,使得类中的某些数据成员,某些成员函数的参数,某些成员函数的返回值,能取任意类型(包括基本类型和用户自定义类型)。

类模版定义:

template<模版参数表>

class 类名

{类成员声明}

在类模版以外定义其成员函数:

template<模版参数表>

类型名 类名<T>::函数名(参数表)


类模版与模版类区别:

类模版是模版的定义,不是一个实实在在的类,定义中用到的通用类型参数。

模版类是实实在在的类定义,是类模版的实例化,类定义中参数被实际类型所代替。

模版实现:

模版定义很特殊,由template<...>处理的任何东西都以为着编译器在当时不为它分配存储空间,它一直处于等待状态直到被一个模版实例告知。所以为了容易使用,几乎总是在头文件中放置全部的模版声明和定义

将程序写的尽可能通用

将算法从特定的数据结构中抽象出来,成为通用的

c++的模版为泛型程序设计奠定了关键的基础

STL是泛型程序设计的一个范例

容器(container)

迭代器(iterator)

算法(algorithms)

函数对象(function object)

容器类是容纳,包含一组元素或元素集合的对象

七种基本容器:

向量(vector)

双端队列(deque)

列表(list)

集合(set)

多重集合(multiset)

映射(map)

多重映射(multimap)

容器接口:

通用容器运算符

==    ,  != ,>    ,  >=   <   ,  <= ,

方法(函数)

迭代方法:

begin(),end(),rebegin(),rend()

访问方法:

size(),max_size(),swap(),empty()

顺序容器的接口

插入方法

push_front(),     push_back(),    insert(),      运算符“=”

删除方法

pop(),     erase()       clear()

其他顺序容器访问方法(不锈钢访问方法)

front()      back()        下标[ ] 运算符


vector使用:

初始化vector容器方法

1:vector<elementType > v ;   //创建一个没有任何元素的空容器

2:vector<elementType > v(other Vec);  //调用拷贝构造函数创建新容器

3:vector<elementType > v(size);           //创建一个大小为size的对象v,并使用默认构造函数初始化该向量

4:vector<elementType > v(n,elem);     //创建一个大小为n的容器,并使用元素elem初始化每一个元素

5:vector<elementType > v(begin,end);//创建容器v,并使用(begin,end)之间的元素初始化容器

元素的插入

1:veclist.push_back(elem);//将elem的一个拷贝插入到veclist的末尾

2:veclist.insert(position,elem);//将elem的一个拷贝插入到指定的position位置上

3:veclist.insert(position,n,elem);//将elem的n个拷贝插入到由position指定的位置上

4:veclist.insert(position,beg,end);//将从迭代器beg至end-1之间的元素插入到veclist的position位置上

#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
int main()
{
vector<int> num;				//STL中的vector容器
int element;
while(cin>>element)				//一直输入,知道输入的是非整数数据为止
{
	num.push_back(element);		//添加到容器末尾
}
for(int i=0;i<num.size();i++)	//访问容器内的元素
{</span>
	cout<<num[i]<<endl;
}
return 0;
}
</pre><p>迭代器是面向对象版本的指针</p><p><span style="white-space:pre"></span>指针可以指向内存中的一个地址</p><p><span style="white-space:pre"></span>迭代器可以指向容器中的一个位置</p><p>STL的每一个容器类模版中,都定义了一组对应的迭代器类</p><p>使用迭代器,算法函数可以访问容器中指定位置的元素,而无需关心元素的具体类型</p><p></p><p>vector<int>::iterator     iter:</p><p><span style="white-space:pre">	</span>这条语句定义了一个名为iter的变量,它的数据类型是由vector<int>定义的iterator类型。</p><p>begin和end 操作</p><p><span style="white-space:pre">	</span>如果容器中有元素的话,由begin返回的迭代器指向第一个元素:</p><p><span style="white-space:pre">	</span>vector<int>::iterator iter=ivec.begin();</p><p><span style="white-space:pre">	</span>由end操作返回的迭代器指向vector的“末端元素的下一个”。通常称为超出末端迭代器(off-the-end iterator)。</p><p></p><p>访问vector 容器中的内容</p><p><span style="white-space:pre">	</span><pre name="code" class="objc">for(vector<int>::size_type ix=0;ix!=ivec.size();++ix)
{
	cout<<ivec[ix]<<endl;	<span style="color:#ff0000;">//用下标方式访问</span>
}

for(vector<int>::iterator iterator=ivec.begin();iter!=ivec.end();++iter)
{
	cout<<*iter<<endl;		<span style="color:#ff0000;">//用iterator访问</span>
}

vector迭代器的自增和解引用运算

for(vector<int>::size_type ix=0;ix!=ivec.size();++ix)
{
	ivec[ix]=0;		<span style="color:#ff0000;">//用下标方式将vector所有元素清0</span>
}

for(vector<int>::iterator iter=ivec.begin();iter!=ivec.end();++iter)
{
	*iter=0;		<span style="color:#ff0000;">//将iterator指向的元素设为0</span>
}

容器的反向遍历

反向遍历是使用迭代器 reverse_iterator

vector<int>::reverse_iterator ri:

rbegin.    rend

反向遍历时使用rbegin,rend来定位

反向遍历迭代器的使用与普通的迭代器一样,可以使用++在位移迭代器,使用*运算符来取元素

vector<int>::reverse_iterator ri=num.rbegin();
while(ri!=num.rend())
{
	cout<<*ri<<" ";
	ri++;
}
cout<<endl;

const_iterator

该类型只能访问容器内元素,但不能改变其值

for(vector<string>::const_iterator iter=text.begin();iter!=text.end();++iter)
{
	cout<<*iter<<endl;
}

const_iterator类型解引用时,则可以得到一个指向const对象的引用,如同任何常量一样,该对象不能进行重写

不要把const_iterator对象与const的iterator对象混淆起来,const的iterator不能做自增减,但可以对它指向的元素赋值

元素的删除

1.veclist.clear()         //清空容器内的所有元素

2.veclist.erase(position)//删除position指定位置的元素

3.veclist.erase(beg,end)//删除beg至end-1直接的元素

4.veclist.pop_back()//删除最后一个元素

vector<int>::iterator iter=num.begin();
num.pop_back();		<span style="color:#ff0000;">//删除最后一个元素</span>
num.erase(iter);	<span style="color:#ff0000;">//删除容器的第一个元素</span>
num.erase(iter,iter+2);		<span style="color:#ff0000;">//删除前2个元素</span>

其他常用函数

1.veclist.capacity();//返回当前可插入到容器veclist的最大数

2.veclist.empty();//判断容器是否为空,为空返回true,否则返回false

3.veclist.size()//判断容器veclist中当前元素个数

4.veclist.max_size()//返回可以插入到容器中元素的最大元素数(可以理解为无穷大)


初始化list容器方法

list容器类有四种形式构造函数

list<elementType> L;	<span style="white-space:pre">	</span><span style="color:#ff0000;">//构造空容器L</span>
list<elementType> L(n,elem);	<span style="color:#ff0000;">//创建一个大小为size的对象L,并使用elem元素进行初始化</span>
list<elementType> L(list1);	<span style="color:#ff0000;">//创建容器L,并使用已创建的容器list1进行初始化</span>
list<elementTYpe> L(begin,end);<span style="color:#ff0000;">	//创建容器L,并使用(begin,end)之间的元素初始化容器</span>
元素的插入

L.push_back(elem);	<span style="color:#ff0000;">//向容器的末尾插入元素elem的拷贝</span>
L.push_front(elem);	<span style="color:#ff0000;">//向容器的开端插入元素elem的拷贝</span>
L.insert(position,elem);	<span style="color:#ff0000;">//向容器的position位置插入元素elem的拷贝</span>
L.insert(position,n,elem);	<span style="color:#ff0000;">//向容器的position位置插入元素elem的n个拷贝</span>
L.insert(position,beg,end);	<span style="color:#ff0000;">//将迭代器beg至end-1指向的内容插入到容器的position位置上</span>
L.splice(position,list);	<span style="color:#ff0000;">//将链表容器list中的元素插入到position位置上,并且清空list容器</span>
L.splice,(position,list,pos);	<span style="color:#cc0000;">//将容器list中的pos位置上的元素插入到position位置上,并将pos位置上的元素从list中移除</span>
L.splice(position,list,beg,end);	<span style="color:#ff0000;">//将容器list中beg至end-1位置上的元素插入到position位置上,并将这些元素从list中移除</span>
元素的删除

L.pop_back();	<span style="color:#ff0000;">//删除容器的最后一个元素</span>
L.pop_front();	<span style="color:#ff0000;">//删除容器的第一个元素</span>
L.clear();		<span style="color:#ff0000;">//删除容器的所有元素</span>
L.erase(position);	<span style="color:#ff0000;">//删除容器指定位置的元素</span>
L.erase(beg,end);	<span style="color:#ff0000;">//删除迭代器beg至end-1之间的元素</span>
L.remove(elem);		<span style="color:#ff0000;">//删除与元素elem相等的元素</span>

例:

#include<list>
#include<iostream>
using namespace std;
int main()
{
list<int> Link;		<span style="color:#ff0000;">//构造一个列表用于存放整数列表</span>
for(int i=0;i<10;i++)
{
	Link.push_front(i);	<span style="color:#ff0000;">//在列表开端插入i</span>
}

Link.insert(Link.end(),10);	<span style="color:#ff0000;">//使用insert在末尾插入数据</span>
Link.remove(5);	<span style="white-space:pre">		</span><span style="color:#ff0000;">//删除5</span>
list<int>::iterator p=Link.begin();	/<span style="color:#ff0000;">/迭代子p用于便利链表</span>
while(p!=Link.end())
{
	cout<<*p<<" ";
	p++;	<span style="white-space:pre">		</span><span style="color:#ff0000;">//p指向下一个节点</span>
}
return 0;
}
<span style="background-color: rgb(192, 192, 192);">skywalker@skywalker:~/work$ ./a.out 
9 8 7 6 4 3 2 1 0 10 </span>

queue应用举例

#include<iostream>
#include<stack>
#include<queue>
using namespace std;

int main()
{
	stack<int>	st;		<span style="color:#ff0000;">//堆</span>
	queue<int>	q;		<span style="color:#ff0000;">//队列</span>
	st.push(1);		<span style="color:#ff0000;">//压入1</span>
	st.push(2);		<span style="color:#ff0000;">//压入2</span>
	st.push(3);
	q.push(100);			<span style="color:#ff0000;">//queue和stack都有push操作</span>
	q.push(200);

	cout<<st.top()<<endl;
	st.pop();
	cout<<st.top()<<endl;
	cout<<q.front()<<endl;
	q.pop();
	cout<<q.front()<<endl;
	while(!st.empty())	<span style="white-space:pre">	</span><span style="color:#ff0000;">//当然queue也能这样用</span>
	{
		int a=st.top();
		cout<<a<<endl;
		st.pop();
	}

}
<span style="background-color: rgb(192, 192, 192);">skywalker@skywalker:~/work$ ./a.out 
3
2
100
200
2
1</span>


map容器

map是STL的一个关联容器,它提供一对一的数据处理能力

其中第一个可以称为关键字,每个关键字只能在map中出现一次

第二个可以称为该关键字的值

map内部所有的数据都是有序的,后边我们会见识到有序的好处

map容器构造

map<elemType,elemType>m://创建空容器

map<elemType,elemType>m(m1);//调用拷贝构造函数来创建容器

map<elemType,elemType>m(beg,end);//使用迭代器beg至end-1区间的数据初始化容器

map<elemType,elemType,greator<const int>>m(beg,end,greater<const int>());//使用迭代器beg至end-1区间的数据和指定的比较函数greater来创建对象


map元素插入

1:用insert函数插入pair数据

2.用insert函数插入value_type数据

3.用数组方式插入数据

以上三种方式都可以插入数据,但是他们是有区别的,其中第一种和第二种在效果上的完成时是一样的,用insert函数插入数据时涉及到集合的唯一性概念,即map中有这个关键字时,insert的操作会失败。而用数组方式插入时,若有这个关键字,它会覆盖以前的关键字对应的值。


insert函数

insert函数的返回值为pair类型,pair容器的第一个类型为当前map容器的迭代器类型,表示元素插入到map容器中的位置,第二个类型为bool类型,表示insert操作是否成功,成功返回true,失败为false

pair<map<int,string>::iterator,bool> insert_pair;

insert_pair=mapStudent.insert(map<int,string>::value_type(1,"student_one"));

map元素访问

1.使用正向迭代器map<elemType,elemType>::iterator       使用begin,end 函数操作

2.使用反向迭代器map<elemType,elemType>::reverse_iterator  使用rbegin,rend函数操作

3.使用常迭代器map<elemType,elemType>::const_iterator  使用begin,end函数操作,但是只能访问,不能修改元素

注:由于map容器的元素是通过转换为pair对象插入到容器中的,因此,要通过pair对象的first和second变量指示出来

map<int,string>::iterator iter;

for(iter=mapStudent.begin();iter!=mapStudent.end();iter++)

{

cout<<iter->first<<"  :"<<iter->second<<endl;

}

map元素删除

1.m.clear(); //删除容器中所有元素

2.m.erase(position); //删除迭代器position位置的元素

3.m.erase(elem); //删除与关键字elem相等的元素

4.m.erase(beg,end); //删除迭代器beg至end-1范围的元素

数据的查找(包括判定这个关键字是否在map中出现)

1.用count函数来判定关键字是否出现

2.用find函数来定位数据出现位置,它返回的是一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器

iter=mapStudent.find();

if(iter!=mapStudent.end())

{  //.....  }

3.Equal_range函数返回一个pair,pair里面第一个变量是lower_bound返回的迭代器,pair里面返回第二个迭代器是upper_bound返回的迭代器,如果这两个迭代器相等的话,则说明map中不存在这个关键字。

#include<map>
#include<string>
#include<iostream>
using namespace std;
int main()
{
	map<int,string>mapStudent;
	mapStudent.insert(pair<int,string>(1,"student_one"));			<span style="color:#ff0000;">//第一种插入方法</span>
	mapStudent.insert(pair<int,string>(1,"student_one1"));
	mapStudent.insert(map<int,string>::value_type(2,"student_two"));	<span style="color:#ff0000;">//第二种插入方法</span>
	mapStudent[3]="student_three";										<span style="color:#ff6600;">//第三种插入方法</span>
	mapStudent[3]="student_three1";
	pair<map<int,string>::iterator,bool>Insert_pair;					<span style="color:#ff0000;">//用来查看是否插入成功</span>
	Insert_pair=mapStudent.insert(pair<int,string>(4,"student_four"));
	if(Insert_pair.second==true)
	{
		cout<<"Insert Successfully"<<endl;
	}
	else
	{
		cout<<"Insert Failure"<<endl;
	}
	map<int,string>::iterator iter;
	for(iter=mapStudent.begin();iter!=mapStudent.end();iter++)			<span style="background-color: rgb(255, 255, 255);"><span style="color:#ff0000;">//用来打印</span></span>
	{
		cout<<iter->first<<":"<<iter->second<<endl;
	}

	iter=mapStudent.find(1);											<span style="color:#ff0000;">//用来查找</span>
	if(iter!=mapStudent.end())
	{
		cout<<"Find  ,the value is :"<<iter->second<<endl;
	}
	else
	{
		cout<<"DO not Find "<<endl;
	}
	iter=mapStudent.find(5);											//用来查找
	if(iter!=mapStudent.end())
	{
		cout<<"Find  ,the value is :"<<iter->second<<endl;
	}
	else
	{
		cout<<"DO not Find "<<endl;
	}
}


<span style="background-color: rgb(204, 204, 204);">skywalker@skywalker:~/work$ ./a.out 
Insert Successfully
1:student_one
2:student_two
3:student_three1
4:student_four
Find  ,the value is :student_one
DO not Find </span>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值