c++学习笔记3_函数模板的使用并实现自己定义的队列

2023-11-08

在这里插入图片描述
实验要求:
熟悉C

1. 函数模板(Function Templates)

重载设计中,最理想的是对不同的参数类型做不同的事情。
比如swap函数,对于任何一个类型T的两个对象a、b,总能调用合适的swap(a,b)——函数模板实现

函数模板的定义:
在这里插入图片描述
关键字template告诉编译器,将要定义一个模板。
<>内的相当于函数的参数列表(模板形参 或 类型参数),每个模板形参都必须加上前缀typenameclass
泛型标识符,例如Typename或T,称为类型参数(Type parameter),这意味这它们类似于变量,但是赋给它们的不能是数字,只能是类型。

例如:

template<class T>
int compare(const T&a,const T&b){
	if(a<b) return -1;
	else if(a>b) return 1;
	else return 0;
} 

模板形参T(T为泛型名),数据形参a、b,函数返回类型int 。

函数模板不是函数,它是以具体的类型参数为实参来生成函数的模板。
函数模板定义被编译时,不会产生任何可执行代码。

类模板(Class Template)

如果让模板来工作,即省心又不降低效率,而且编译器依然可以对代码进行类型检查,还能保持代码的优雅和简洁。

类模板是一种模板,它通过在类定义上铺设类型参数的形式,表示具有相似操作的系列类(类族)。
template< class T> class Queue;中的Queue,即类模板名(class template name),简称模板名(template name)

类模板不是类,而模板类是类。

template<class T> 
class Queue;
template<class T> 
class QueueItem{
//public:
private:
	T item;
	QueueItem *next;
	friend Queue<T>;
	QueueItem(const T &t):item(t),next(){}
//	friend ostream & operator<<(ostream &os,Queue<T> &q);
	friend ostream & operator<<(ostream &os,const Queue<T> &q);
};

template<class T> 
class Queue{
private:
	QueueItem<T> *head;
	QueueItem<T> *tail;
	//friend ostream & operator<<(ostream &os,const Queue<T> &q);
	friend ostream & operator<<(ostream &os,const Queue<T> &q){
		QueueItem<T> *p=q.head;
	//	Queue<T> *p=q.head;
		os<<"< ";
		while(p){
			os<<p->item<<" ";
			p=p->next;
		}
		os<<">"<<endl;
		return os;
	}
	void Destroy();
public:
	Queue():head(0),tail(0){}
	Queue(const Queue<T> &q){
		copyItems(q);
	}
	void push(const T &t);
	void pop();
	bool isEmpty(){
		return head==0;
	}
	T & front(){
		if(!isEmpty()){
			return head->item;
		}
	}
	~Queue(){
		Destroy();
	}
	void copyItems(const Queue<T> &q);

	template<class It>
	void copyItems(It beg,It end);
	template<class It>
	Queue(It beg,It end):head(0),tail(0){
		copyItems(beg,end);
	}
	template<class It>
	void assign(It beg,It end);
	Queue & operator=(const Queue&);
	Queue & operator()(const Queue&);
};

类模板实例化的过程,是根据具体的模板实参,替换成模板形参而产生除对应的模板类的过程。
例如:

Queue<int> l1;

模板特化

可以用模板实参来定做模板类。
类模板的模板实参通过实例化,构成模板的实例,它是定义好的模板类。
如果不想使用预定义的类模板来生成模板类,则是以该模板类名自己专门重写一个模板类,则得到模板特化(template specialization),得到模板特化的过程,称为模板定做(template specializing)

模板定做时, template<> class 类模板名

以下为局部定做(partial specialization)
申明(放在.h文件中) :

template<>
int compare<const char*>(const char * const &v1, const char * const &v2);

template<>
void Queue<const char*>::push(const char* const &t);

template<>
void Queue<const char*>::pop();

实现(只能放在.cpp文件中):

template<>
void Queue<const char*>::push(const char* const &t){
	char *p=new char [strlen(t)+1];
	strncpy(p,t,strlen(t)+1);
	QueueItem<const char*>*qi=new QueueItem<const char*>(p);
	if(isEmpty()){
		head=tail=qi;
	}
	else{
		tail->next=qi;
		tail=qi;
	}
}

template<>
void Queue<const char*>::pop(){
	QueueItem<const char*>*qi=head;
	head=head->next;
	delete[] qi->item;
	delete qi;
}

template<>
int compare<const char*>(const  char* const &a,const  char* const &b){
	return strcmp(a,b);
}

实验部分

(熟悉C++的函数模板的使用并实现自己定义的队列)

sy3.h

#ifndef sy3
#define sy3
#include <iostream>
#include <string.h>
using namespace std;
template<class T> 
class Queue;

template<class T> 
class QueueItem{
//public:
private:
	T item;
	QueueItem *next;
//	friend Queue<T>;
	friend Queue<T>;
	QueueItem(const T &t):item(t),next(){}
//	friend ostream & operator<<(ostream &os,Queue<T> &q);
	friend ostream & operator<<(ostream &os,const Queue<T> &q);
};

template<class T> 
class Queue{
private:
	QueueItem<T> *head;
	QueueItem<T> *tail;
	//friend ostream & operator<<(ostream &os,const Queue<T> &q);
	friend ostream & operator<<(ostream &os,const Queue<T> &q){
		QueueItem<T> *p=q.head;
	//	Queue<T> *p=q.head;
		os<<"< ";
		while(p){
			os<<p->item<<" ";
			p=p->next;
		}
		os<<">"<<endl;
		return os;
	}
	void Destroy();
public:
	Queue():head(0),tail(0){}
	Queue(const Queue<T> &q){
		copyItems(q);
	}
	void push(const T &t);
	void pop();
	bool isEmpty(){
		return head==0;
	}
	T & front(){
		if(!isEmpty()){
			return head->item;
		}
	}
	~Queue(){
		Destroy();
	}
	void copyItems(const Queue<T> &q);

	template<class It>
	void copyItems(It beg,It end);
	template<class It>
	Queue(It beg,It end):head(0),tail(0){
		copyItems(beg,end);
	}
	template<class It>
	void assign(It beg,It end);
	Queue & operator=(const Queue&);
	Queue & operator()(const Queue&);
};



template<class T>
void Queue<T>::push(const T &t){
	QueueItem<T> *pItem = new QueueItem<T>(t);
	if(isEmpty()){
		head=tail=pItem;
	}
	else{
		tail->next=pItem;
		tail=pItem;
	}
}


template<class T>
void Queue<T>::pop(){
	if(isEmpty())
		return;
	QueueItem<T> *p=head;
	head=head->next;
	delete p;
}

template<>
void Queue<const char*>::push(const char* const &t);
template<>
void Queue<const char*>::pop();

template<class T>
void Queue<T>::Destroy(){
	while(!isEmpty()){
		pop();
	}
}
template<class T>
void Queue<T>::copyItems(const Queue<T> &q){
	QueueItem<T> *p=q.head;
	while(p){
		push(p->item);
		p=p->next;
	}
}
template<class T>
template<class It>
void Queue<T>::copyItems(It beg,It end){
	while(beg!=end){
		push(beg);
		beg++;
	}
}

template<class T>
Queue<T> &Queue<T>::operator=(const Queue & q){
	Destroy();
	copyItems(q);
} 
template<class T>
Queue<T> &Queue<T>::operator()(const Queue & q){
	Destroy();
	copyItems(q);
} 
template<class T>
template<class It>
void Queue<T>::assign(It beg,It end){
	Destroy();
	copyItems(beg,end);
}

template<class T>
int compare(const T&a,const T&b){
	if(a<b) return -1;
	else if(a>b) return 1;
	else return 0;
} 
template<>
int compare<const char*>(const  char* const &a,const  char* const &b);

#endif

sy3.cpp

#include "sy3.h"
#include<string>
#include<string.h>
using namespace std;

//类部分模板特化 
template<>
void Queue<const char*>::push(const char* const &t){
	char *p=new char [strlen(t)+1];
	strncpy(p,t,strlen(t)+1);
	QueueItem<const char*>*qi=new QueueItem<const char*>(p);
	if(isEmpty()){
		head=tail=qi;
	}
	else{
		tail->next=qi;
		tail=qi;
	}
}

template<>
void Queue<const char*>::pop(){
	QueueItem<const char*>*qi=head;
	head=head->next;
	delete[] qi->item;
	delete qi;
}

template<>
int compare<const char*>(const  char* const &a,const  char* const &b){
	return strcmp(a,b);
}

main.cpp

#include <iostream>
#include "sy3.h"
using namespace std;

//class Queue 的使用
int main() {
	Queue<int> l1;
	int a=1,b=2,c=3;
	l1.push(a);
	l1.push(b);
	l1.push(c);
	cout<<"l1"<<l1; 
	l1.pop();
	cout<<"l1"<<l1;
	
	Queue<double> l2;
	double d=1.1,e=2.2,f=3.3;
	l2.push(d);
	l2.push(e);
	l2.push(f);
	cout<<"l2"<<l2; 
	double front=l2.front();
	cout<<l2.front()<<endl;
	
	int x[5]={1,2,3,4,5};
	int y[5]={11,12,13,14,15};
	Queue<int> l3(1,4);
	cout<<"l3"<<l3; 
	Queue<double> l4;
	l4.copyItems(l2);
	cout<<"l4"<<l4; 
	
	Queue<int> l5;
	l5.copyItems(11,15);
	cout<<"l5"<<l5; 
	Queue<double> l6;
	l6(l4);
	cout<<"l6"<<l6; 
	Queue<int> l7;
	//l7=l4;
	l7.copyItems(1,3);
	cout<<"l7"<<l7; 	
	cout<<"compare(2,12)"<<compare(2,12)<<endl;
	cout<<"------------------------------------------"<<endl;
	cout<<"compare('ad','ab')"<<compare('ad','ab')<<endl;
	Queue<const char*>q1;
	q1.push("q1");
	q1.push("is");
	q1.push("there");
	cout<<"q1"<<q1;
	q1.pop();
	cout<<"q1"<<q1;
	
/**/	
	Queue<const char*>q2;
	//q2.copyItems(q1);
	q2(q1);
	cout<<"q2"<<q2;
	
	Queue<const char*>q3;
	q3=q1;
	cout<<"q3"<<q2;
	return 0;
}

运行结果:

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++学习笔记3_函数模板的使用并实现自己定义的队列 的相关文章

随机推荐

  • mac下pycharm使用小技巧--持续更新

    Pycharm使用小技巧 pycharm创建新文件自动添加文件头注释 背景 我们平时在使用pycharm发现有些大神创建一个新文件的时候会自动在文件头添加一些注释 像是有文件路径 创建时间 创建人 集成平台等信息 但是我们自己创建的时候就没
  • 论文翻译:2021_Performance optimizations on deep noise suppression models

    Python微信订餐小程序课程视频 https blog csdn net m0 56069948 article details 122285951 Python实战量化交易理财系统 https blog csdn net m0 5606
  • 快速排序---从大到小和从小到大(Java)

    快速排序 快速排序由于排序效率在同为O nlogn 的几种排序方法中效率较高 因此经常被采用 再加上快速排序使用了分治法的思想 算是基础排序中比较高档的一种排序了 基本思想 1 先从数列中取出一个数作为基准数 可以是第一个 也可是中间的或者
  • 大数据系统体系架构(含图示)

    目录 1 大数据体系架构图 2 数据采集层 3 数据计算层 4 数据服务层 5 数据应用层 1 大数据体系架构图 2 数据采集层 阿里的的日志采集包括两大体系 Aplus JS是Web端的日志采集技术方案 UserTrack是APP端的日志
  • 前后端分离案例--权限系统(跨域请求)

    权限系统 1 前端 vue elementui axios css html 2 后端 springboot mybatis plus nybatis druid shiro swagger2 redis 1 前端界面及按钮事件实现 1 1
  • thrift介绍及应用(一)—介绍

    原文 http blog csdn net guxch article details 12157151 一 概述 Thrift是Apache下的一个子项目 最早是Facebook的项目 后来Facebook提供给Apache作为开源项目
  • 如何判断一个List集合中是否有空值

    list Any v gt string IsNullOrWhiteSpace v 转载于 https www cnblogs com xiaonangua p 10818082 html
  • ifdef win32 linux,使用预定义宏检测编译环境(操作系统、编译器类型、编译器版本)...

    在编写跨平台的程序时 我们经常使用预定义宏来检测编译环境 虽然编译器的手册中有预处理宏的介绍 但是不够详细 而且还有很多宏没有介绍 于是 我编写了一个小程序 显示常见C C 编译器的编译器的预定义宏 一 心得 最直接的办法是逐个逐个的用 i
  • 第一次团队展示

    组长本次团队展示链接 拟作的团队项目描述 致力于让现代学生生活更加轻松 队员风采 宋奕 风格 工作时候认真 生活上快乐 擅长的技术 java dotnet c 编程兴趣 通过不断地完成项目来提升技术和能力 希望的软工角色 项管兼后端 一句话
  • python案例:用户画像分析

    目录 1 项目背景 数据 2 标记高潜用户 3 基于高潜用户信息进行分析 3 1 筛选高潜用户静态数据 3 2 高潜客户的客户等级分布 3 3 高潜用户的年龄段对比 3 4 根据df ac cate 和高潜用户id匹配出高潜用户的购买该商品
  • Barman离线安装(一步到位)

    软件版本信息 软件版本 CentOS Linux release 7 8 2003 Core Python 3 6 8 pip 9 0 3 from usr lib python3 6 site packages python 3 6 ps
  • @JSONField的用法

    主要用在JSON格式和JAVA对象之间进行传递的时候有很大的用处 由于JSON中的key与bean中的属性不能匹配 因此在转换过程中出现了部分属性为null的情况 如下 package test import com alibaba fas
  • 【DL】第7章 推荐表情符号

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • MATLAB笔记 sparse稀疏矩阵函数

    sparse 函数功能 生成稀疏矩阵 使用方法 S sparse A 将矩阵A转化为稀疏矩阵形式 即矩阵A中任何0元素被去除 非零元素及其下标组成矩阵S 如果A本身是稀疏的 sparse S 返回S S sparse i j s m n n
  • 【XGBoost】第 8 章:XGBoost 替代基础学习器

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • yolov3算法检测单类物体

    yolov3是目前目标检测类检测效果和检测速度最好的算法 原版的yolov3检测的物体种类众多 本文实在原有yolov3上将多累物体检测简化为单类物体检测 本文的原始代码基于github上copy的 源码下载地址为 https github
  • WebStorm开发插件

    目录 目录 1 图标插件 Atom Material Icons 2 Translation 3 彩色括号 Rainbow Brackets 4 高亮括号 HighlightBracketPair 5 代码缩略图 CodeGlance2 6
  • 关于Directly Mapping Texels to Pixels的例子

    原文 http msdn microsoft com en us library bb219690 28v vs 85 29 aspx 是关于在direct3d9中 对于屏幕空间中 将贴图映射到像素的问题 以下是pixel shader源代
  • c语言在线编译网页版,c语言在线编译器(c语言网页版在线编译器)

    不好意 我想要的是下载 点 问题没说清楚 sorry dev c 选择什么样的编译器对我学习C语言来说重要么 在线等大神指点 不要复制 学习C语言的话 VC基本上就差不多了 小巧 方便 启动快 而VS是大软件 启动时有点慢 GCC是linu
  • c++学习笔记3_函数模板的使用并实现自己定义的队列

    实验要求 熟悉C 目录 1 函数模板 Function Templates 类模板 Class Template 模板特化 实验部分 sy3 h sy3 cpp main cpp 运行结果 1 函数模板 Function Templates