C++笔记_04C++模版1

来源:互联网 发布:淘宝女人秋装 编辑:程序博客网 时间:2024/06/03 16:57
#include<iostream>


using namespace std;


/*
oop三大特征
封装  继承 多态
第二部分  模版
《C++ templates》
1.函数模版
2.类模板




需要搞清楚的知识点


函数模版
模版的实例化,(显示, 隐式)
模版函数
模版的实参推演


模版类型参数
模版的非类型参数




模版的特例化(专用化)
模版函数的重载
*/




/*
int sum(int a,int b);  a,b 实参的值进行参数化
模版就是将类型也进行参数化


*/




/*


*1*模版的代码内容实例化之前不进行编译
*2*因为1 ,所以当它没有任何的实例化(也就是没有产生任何函数),所以,对于模版的代码不能写到头文件里,
所以,在模版的调用处,一定要看到模版的定义处,光声明不可以
想在头文件里写,就必须显示实例化




*/
//语法:定义模版的参数列表    可定义   类型参数/非类型参数  class/typename
//template<class CT>      //类类型
//template<typename T>   //非类类型参数
//template<typename T1,typename T2>//可定义多个,一般都是大写




#if 1


/*
类模版
链表
*/


//前向声明
template<typename T>
class CLink;




//类模版 除了构造和析构函数的名字 可以省略参数列表(模版的参数列表<typename T>),其他地方不能省略
template<typename T>  //Node<int>
class Node
{
public:
typedef int T;
Node(T data = T()):_data(data),_pnext(NULL){};
private:
T _data;
Node<T> *_pnext;


//template<typename T>    //CLink<int> CLink<char>  CLink<int *> 
//friend class CLink;
friend class CLink<T>;//声明模版CLink,,T特例化,,要是用这个得在前面进行前向声明
};
//可以看出,不同模版的参数名可以用在不同模版出,也就是相同的模版参数名,不在同一作用域处就可以重名








template<typename T=int>
class CLink
{
public:
CLink()
{
_phead = new Node<T>();
}


~CLink()
{
Node<T> *pcur = _phead;
while(pcur != NULL)
{
_phead = _phead->_pnext;
delete pcur;
pcur = _phead;
}
}


void insertHead(const T &val);


void show()
{
Node<T> *pcur = _phead->_pnext;
while(pcur!=NULL)
{
cout<<pcur->_data<<" ";
pcur = pcur->_pnext;
}
cout<<endl;
}
private:
//作业:  写 嵌套类  class Node



Node<T> *_phead;//Node是一个模版名,但是指针前面需要类型,在这里模版不在它的定义体内,所以需要一个模版参数来实例化


};


template<typename T>
void CLink<T>::insertHead(const T &val)
{
Node<T> *ptmp = new Node<T>(val);
ptmp->_pnext = _phead->_pnext;
_phead->_pnext = ptmp;
}










int main()
{
//类模版的选择性实例化
CLink<int> link1;
//CLink<> link2;
//CLink<double> link3;
//CLink<CLink<int>> link4;//可以当做二维链表使用


link1.insertHead(10);
link1.insertHead(11);
link1.insertHead(12);
link1.insertHead(13);
link1.insertHead(14);
link1.show();




return 0;
}






#endif






#if 0


//函数模版不支持给默认值,但是类模板支持
template<typename T>
int findValIndex(T *array,int length,const T &val)
{
for(int i=0;i<length;++i)
{
if(array[i] == val)
{
return i;
}
}
return -1;
}


//char *特例化
template<>
int findValIndex<char *>(char **array,int length,char *const &val)
{
cout<<"findValIndex<char *>"<<endl;
for(int i=0;i<length;i++) 
{
if(strcmp(array[i],val)==0)
{
return i;
}
}
return -1;
}


int main()
{
int array[] = {2,45,7,78,90,31};
int length = sizeof(array)/sizeof(array[0]);
int index = -1;


index = findValIndex(array,length,78);
if(index == -1)
{
return -1;
}
cout<<"78 index is:"<<index<<endl;


char *strArr[] = {"hello","world","sdafs","tyri57"};
length = sizeof(strArr)/sizeof(strArr[0]);


index = findValIndex<char *>(strArr,length,"sdafs");
if(index == -1)
{
return -1;
}
cout<<"sdafs index is:"<<index<<endl;




return 0;
}
#endif






#if 0
/* 模版的特例化(专用化) */
template<typename T>
bool compare(T a,T b)
{
cout<<typeid(T).name()<<endl;
cout<<typeid(a).name()<<endl;
cout<<typeid(b).name()<<endl;
cout<<"template compare<T>"<<endl;

return a>b;
}


/*
对于特例化,应当提供该特例化(专用化)的处理版本


对于函数来说,  只支持模版的完全特例化,不支持模版的部分特例化(只有类模版才支持)
*/


template<>
bool compare<char *>(char *a,char *b)
{
cout<<"compare<char *>(char  *,char *)"<<endl;
return strcmp(a,b) > 0 ? true : false;
}


template<>
bool compare<int>(int a,int b)
{
cout<<"compare<int>(int,int)"<<endl;
return a>b;
}


template<>
bool compare<const int>(const int a,const int b)
{
//compare<int>(10,20);
cout<<"compare<const int>(const int,const int)"<<endl;
return a>b;
}


//非模版函数
//函数模版 模版的特例化 非模版函数   可以共从,,   调用顺序, 非模版函数->模版的特例化->模版函数


bool compare(int a,int b)
{
cout<<"compare<int>(int,int)"<<endl;
return a>b;
}




int main()
{
compare<int>(10,20);   //有特例化版本,优先使用特例化版本
compare<char *>("hello","world!"); //const char *   常量字符串


compare("hello","world!");//这种情况,编译器不会优先使用特例化版本,而是先自己根据模版进行实例化
compare(20,20);


//int a=10;
//const int b=10;
//cout<<typeid(a).name()<<endl;// int 
//cout<<typeid(b).name()<<endl;// int   打印出来 两个类型一样的




return 0;
}
#endif


#if 0


template<typename T>
bool compare(const T a,const T b)//此处const修饰的是a,b变量名
{
cout<<typeid(T).name()<<endl;
cout<<typeid(a).name()<<endl;
cout<<typeid(b).name()<<endl;
cout<<"template compare<T>"<<endl;
return a>b;
}


template<>
bool compare<char *>(char * const a,char * const b)//此处const修饰的是a,b变量名,所以特例化的时候const要修饰a ,b
{
cout<<"compare<char *>(char * const a,char * const b)"<<endl;
return strcmp(a,b) > 0 ? true : false;;
}


/*
#define T int
typedef int T;


const T a;


#define T char *
typedef char *T;


const T b;
*/




template<typename T,int SIZE>//int SIZE 是非模版类型参数,不能作为左值, 本身是常量,所以传入必须的常量
void sort(T arr[])
{
T tmp=0;//T() 零初始化 零构造
for(int i=0;i<SIZE-1;++i)
{
for(int j=0;j<SIZE-1-i;++j)
{
if(arr[j] > arr[j+1])
{
tmp = arr[j];
arr[j]=arr[j+1];
arr[j+1]=tmp;
}
}
}
}


template void sort<int>(int arr[],int size);//特例化


template<int SIZE> //template<char SIZE>  template<short SIZE>  template<float SIZE> template<int& SIZE>
void func()
{
/*
非类型模版参数仅限于整数类型,,  包括整数类型的指针,引用
*/
}


//冒泡排序
template<typename T>
void sort(T arr[],int n)
{
T tmp=0;//T() 零初始化 零构造
for(int i=0;i<n-1;++i)
{
for(int j=0;j<n-1-i;++j)
{
if(arr[j] > arr[j+1])
{
tmp = arr[j];
arr[j]=arr[j+1];
arr[j+1]=tmp;
}
}
}
}




int main()
{
int array[10];
for(int i=0;i<10;++i)
{
array[i]=rand()%100+1;
}
//template void sort<int>( int arr[],int n);   //显示实例化,当函数调用点和函数定义不处于同一个文件中
//sort<int>(array ,10 )


//常量与常变量
const int size = sizeof(array)/sizeof(array[0]);//常量  
// int length = sizeof(array)/sizeof(array[0]);
// const int size = length;//常变量没有给一个明确的初始值






sort(array,size);


for(int i=0;i<10;++i)
{
cout<<array[i]<<" ";
}
cout<<endl;
}
#endif






#if 0
template<typename T>
bool compare(T a,T b)
{
cout<<typeid(T).name()<<endl;
cout<<typeid(a).name()<<endl;
cout<<typeid(b).name()<<endl;
cout<<"template compare<T>"<<endl;
return a>b;
}


//template<typename T,typename E>
//bool compare(T a,E b)
//{
// cout<<typeid(T).name()<<endl;
// cout<<typeid(a).name()<<endl;
// cout<<typeid(b).name()<<endl;
// cout<<"template compare<T,E>"<<endl;
// return a>b;
//}


//函数模版 -> 实例化 -> 模版函数
/*
//模版函数
bool compare(int a,int b)
{
cout<<"template compare"<<endl;
return a>b;
}
*/




//显示实例化
template bool compare<int>(int,int);
template bool compare<double>(double,double);
template bool compare<float>(float,float);








int main()
{
//int -> compare  实例化模版
compare<int>(10,20);
compare<double>(10.5,20.5);
compare<float>(10.5,20.5);


//模版的实参推演  实参的类型 -> 推演 -> 模版实例化  [只有当模版参数类型出现在参数列表里才可以]
compare(10,20);
//compare(10.5,20);
//以上实例化都是隐式实例化  (没有指定类型,都是编译器自动实例化)












return 0;
}
#endif
原创粉丝点击