C++模板&泛型编程
---恢复内容开始---
一、泛型编程
定义:编写与类型无关的逻辑代码,是代码复用的一种手段。模板是泛型编程的基础
模板分为:函数模板和类模板
函数模板:代表了一个函数家族,该函数与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。
函数模板的格式:template<typename p1,typename p2,...,typename p> //typename和class都可以定义模板参数一般建议使用typelate好理解和类关键字区分
返回值类型 函数名(参数列表)
{...}
模板是蓝图,本身不是类或者函数,编译器用模板产生特定的类或者函数的特定类型版本,产生模板特定类型的过程成为模板的实类化
定义模板关键字:T是模板参数名字可以任意命名,下面代码返回值是T类型这个很重要
1 template<typename T>
T Add(T left,T right)
{
return left+right;
} int main()
{
cout<<Add(,)<<endl;;
return ;
}
//给main()函数里加一句cout<<Add(1.2,2.3)<<endl;函数模板将被编译两次
// 1.实类化之前,检查模板代码本身,查看是否出现语法错误,如:遗漏分号。2.在实类化期间,检查模板代码,查看是否所有的调用都有效,如:实类化理性不支持某些函数调用
这个返回值是T1,配合下面代码就是int ,函数返回值类型很重要,所以这里还是认真点
1 template<typename T1,typename T2>
T1 Add(T1 left,T2 right)
{
return left+right;
} int main()
{
cout<<Add(,'')<<endl;;
return ;
}
模板函数也可以定义为inline函数
template<typename T1,typename T2>
inline T2 Add(T1 left,T2 right)
{
return left+right;
} int main()
{
cout<<Add(,'')<<endl;;
return ;
}
//返回值是字符3
模板参数:
模板函数有两种类型形参:模板参数和调用参数
模板形参分为:类型形参和非类型形参
//模板形参名字只能在模板形参之后到模板声明或定义的末尾之间使用,遵循名字屏蔽规则
1 typedef int T;
template<typename T>
void FunTest(T t)
{
cout<<"t type = "<<typeid(t).name()<<endl;
}
T gloab;
int main()
{
FunTest();
cout<<"gloab type = "<<typeid(gloab).name()<<endl;
return ;
}
eg:判断下面函数定义是否有问题
//template<class T,U,typename V>
//void F1(T,U,V);
//模板参数不能这样定义,模板参数前必须加上定义模板参数关键字class或者typeame
//template<class T>
//T F2(int &T); //template<class T>
//T F3(T,T);
//typedef int TYPENAME;
//template<typename TYPENAME>
//TYPENAME F4(TYPENAME);
模板函数重载:
主要看看下列情况调用哪个函数
1 int Max(const int& left,const int& right)//
{
return (left>right)?left:right;
}
template<typename T> //
T Max(const T& left,const T&right)
{
return (left>right)?left:right;
}
template<typename T> //
T Max(const T& a,const T& b,const T& c)
{
return Max(Max(a,b),c);
}
int main()
{
Max(,,);//3
Max<>(,);//2
Max(,); //1
Max(,20.0);//1
Max<int>(10.0,20.0);//2
Max(10.0,20.0);//2
return ;
}
//注意:函数的所有重载版本的是声明都应该位于该函数被调用位置之前
二、模板函数特化
在某些情况下,通用模板定义对于某个类型可能是完全错误的,或者不能编译,或者做一些错误的事情
template<class T>
int compare(T t1,T t2)
{
if(t1>t2)
return ;
else if(t1<t2)
return -;
else
return ;
}
int main()
{
char *pStr1="holle";
char *pStr2="world";
cout<<compare(pStr1,pStr2)<<endl;
return ;
}
//结果是1,实际是-1
模板函数特化形式:
1、关键字template后面跟一个空的<>
2、再接模板名和<模板形参>
3、函数形参表
4、函数体
三、模板类
模板类型格式
template<typename p1,typename p2,...,typename p>
class 类名
{...}
eg:
1 template<typename T>
class SeqList
{
private:
T* _Data;
int _size;
int _capacity
}
//以模板方式实现动态顺序表 template<typename T>
class SeqList
{
public:
SeqList();
~SeqList();
private:
int _size;
int _capacity;
T* _Data;
};
template<typename T>
SeqList<T>::SeqList()
:_size()
,_capacity()
,_Data(new T[_capacity])
{}
template<typename T>
SeqList<T>::~SeqList()
{
delete []_Data;
}
void FunTest()
{
//SeqList Seq;
SeqList<int>s1;
SeqList<double>s2;
}
//有一种不同的类型编译器就会实类化出对应的一个类
---恢复内容结束---
C++模板&泛型编程的更多相关文章
- c++模板 与 泛型编程基础
C++模板 泛型编程就是以独立于任何特定类型的方式编写代码,而模板是泛型编程的基础. (1)定义函数模板(function template) 函数模板是一个独立于类型的函数,可以产生函数的特定类型版 ...
- 论C++与三国
Scott Meyers曾说过,C++语言是一个语言联邦.C++包含面向过程,面向对象,泛型编程编程思想.现在C++11有加了一堆新特性,语言联邦更为庞大. 程序员们.常常挑起语言之争,甚至连大师级人 ...
- C++11--20分钟了解C++11 (下)
20分钟了解C++11 9 override关键字 (虚函数使用) * * 避免在派生类中意外地生成新函数 */ // C++ 03 class Dog { virtual void A(int); ...
- 《C++ Primer Plus》学习笔记 第1章 预备知识
第一章 预备知识C++在C语言的基础上添加了对"面向对象编程"的支持和对"泛型编程"的支持.类 —— 面向对象模板 —— 泛型编程1.1 C++简介1.2 C+ ...
- infos
C++文件流 iostream 提供了cin cout 分别用于从标准输入读取流和向标准输出写入流cout 标准输出 屏幕 输出写入fstream文件流 cin 从标准输入读取cout 向标准输入写入 ...
- C++泛型编程:template模板
泛型编程就是以独立于任何特定类型的方式编写代码,而模板是C++泛型编程的基础. 所谓template,是针对“一个或多个尚未明确的类型”所编写的函数或类. 使用template时,可以显示的或隐示的将 ...
- c++ 泛型编程及模板学习
泛型编程,英文叫做Generic programming 可以理解为,具有通用意义的.普适性的,编程. 比如,你要实现一个函数去比较两个数值的大小,数值可能是int或者string.初次尝试,我们直观 ...
- C++ 模板与泛型编程
<C++ Primer 4th>读书笔记 所谓泛型编程就是以独立于任何特定类型的方式编写代码.泛型编程与面向对象编程一样,都依赖于某种形式的多态性. 面向对象编程中的多态性在运行时应用于存 ...
- 泛型编程、STL的概念、STL模板思想及其六大组件的关系,以及泛型编程(GP)、STL、面向对象编程(OOP)、C++之间的关系
2013-08-11 10:46:39 介绍STL模板的书,有两本比较经典: 一本是<Generic Programming and the STL>,中文翻译为<泛型编程与STL& ...
随机推荐
- Object.create()方法的低版本兼容问题
Object.prototype.create=(function(){ if(Object.prototype.create){return Object.prototype.create}else ...
- RPM包的制作
RPM包的制作 前言 按照其软件包的格式来划分,常见的Linux发行版主要可以分为两类,类ReadHat系列和类Debian系列,这两类系统分别提供了自己的软件包管理系统和相应的工具. 类RedHat ...
- 【CodeVS1080】线段树练习
Description 一行N个方格,开始每个格子里都有一个整数.现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和:修改的规则是指定某一个格子x,加上或者减去一个 ...
- Modern C++ CHAPTER 2(读书笔记)
CHAPTER 2 Recipe 2-1. Initializing Variables Recipe 2-2. Initializing Objects with Initializer Lists ...
- WPF Image控件的Source属性是一个ImageSource对象
1.固定的图片路径是可以的,如下: <Image Source="../test.png" /> 2.绑定的Path是一个String类型的图片路径,而实际情况它需要的 ...
- shell---变量自增
我所知道的,bash中,目前有五种方法:1. i=`expr $i + 1`;2. let i+=1;3. (( i++ ));4. i=$[ $i+1 ];5. i=$(( $i + 1 ))
- Sql Server 行转列
--摘自百度 PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (… ...
- c#datagirdview ,用DataSource 方式赋值,然后更新出问题问题
先说一下程序 主窗体 ,两个子窗体A,B.嵌入主窗体的Panel里边 主窗体,启动类C里边的查找方法,查到的值,通过事件委托送到窗体A C类里同时修改查询表,把修改的查询表通过事件委托发送给窗体B, ...
- 引用64位dll时候出现 未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项。试图加载格式不正确的程序。
引用64位dll时候出现 未能加载文件或程序集“System.Data.SQLite”或它的某一个依赖项.试图加载格式不正确的程序. 需要在web.config增加配置 <startup use ...
- moss2003 sp3补丁安装
安装完成以后自己在产品库里增加的存储过程不见了,自我保护?