oop语言三大特征 封装 继承 多态
类模板
编写泛型代码、STL最重要的手段
函数模板:类型也进行参数化
模板实例化(显示实例化 隐式实例化)
语法:
1、定义模板参数列表 类型参数/非类型参数
template<typename T>//定义了一个模板参数列表 用来接收一个类型持续到右大括号前
//模板不进行编译 不产生符号 只检查原型{}之间的东西不检测
//像内联函数
bool compare(T a,T b)
{
cout<<"trmplate compare"<<endl;
renturn a>b;
}
int main()
{
//int ---》(实例化模板)int compare<int> 函数模板-》实例化-》模板函数 调用优先级
compare<int>(10,20);//用int来替换T
return 0;
}
自己写的时候 只写一个模板 编译器自动实例化出模板函数
静多态 :模板 重载
指定具体的类型参数 <int>模板实例化之后才可以用 不然等与函数名 模板函数 在.text段
模板实参推演 自动推演出模板实参类型参数//???为啥第二种不行?
无法推出返回值
模板类型参数都出现在形参列表里才可以推演
调用和定义写在不同的文件 --》不会实例化 编译处不会展开 不产生符号
如果非要写在源文件中 必须显示实例化
模板实现 sort
void sort(T array[],int size)
{
int i = 0 ;
int j = 0 ;
T temp;
for(i = 0; i<size-1-i;++i)
{
for(j = 0;j<size -1;++j)
{
if(array[j]<array[j+1])
{
temp = arr[j];
arr[j]= arr[j+1];
arr[j+1]= temp;
}
reutrn ;
}
}
零初始化 零构造 T temp = T();
模板在调用点 编译阶段实例化出要用的实例化类型 所以静多态
模板的特例化(专用化)const char * 类型不匹配 char *
bool compare<char *>(char* const a,char * const b)
{
return strcmp(a,b)>0;
}
int findValue<char *>(char const **array,int size,const char * &val)
{
for(int i = 0;i<size;++i)
{
if(strcmp(array[i] == val))
{
return i;
}
return -1;
}
}
常字符串 ROdata段 char *栈上
优先调用 非模板函数
函数模板 只支持模板的完全特例化 不支持模板的部分特例化(只有类模板才支持)
重载:1、函数名相同参数列表不同 2、const修饰指针引用 3、同一个作用域,
模板的类型参数和非类型参数
非类型参数
1、必须是一个常量 不能被修改
2、非类型参数如果接收值只能是整型
3、或者其他任意类型的指针或引用
int main()
{
int intArr[]={12,3,4,56,31,21};
sort<int, 6>(intArr);
char* array[]={"hello", "world", "china"};
int size = sizeof(array)/sizeof(array[0]);
/*
可能是“const char [6]”
1> 或 “char *”
*/
cout<<findValue<char*>(array, size, "world")<<endl;
char a[]="world";
cout<<findValue<char*>(array, size, a)<<endl;
}
//单链表
template<typename T>
class Node
{
public:
//零构造
Node(T data = T()):mdata(data), mpnext(NULL){}
private:
T mdata;
Node<T> *mpnext;
//定义友元类 一对多的关系
//template<typename E>
//friend class Link;
//定义一对一的友元关系
friend class Link<T>;
};
link<T>::link()
{
mphead = new Node<T>();
}
template<typename T>
link::~link()
{
Node<T> *pcur = mphead;
whlie(pcur != NULL)
{
mphead = mphead->mpnext;
delete pcur ;
pcur = mphead;
}
}
类模板
构造 、 析构 可省略<T>
类模板选择性实例化
一个类里面有很多方法访问另一个类的私有成员 -》友元类
一个全局方法里面访问另一个类的私有成员 -》友元函数
内层T 作用域 覆盖外层T
友元类 一对多没有意义 (,)<,>∵从右往左编译
友元类的前置声明
template<typename T>
friend class link;
一对一 其他类型的Link都可作为int型Node的友元类 不过一对一int对int 最有意义。
隐式生成临时对象 是个常量 用 const 接收 拷贝构造
#define T int 预编译阶段 字符串替换 所以 unsigned int 可以;
typedef E int; 编译阶段 编译器会认为 用两个类型修饰 (unsigned/int)所以不可以。