1.函数模板:
template <typename T>
void myswap(T &a,T&b) {
T c;
c=a;
a=b;
b=c;
}
//函数模板调用
void main(){
int x=10,y=20;
char a='a',b='b';
myswap<int>(x,y);//显示类型调用
myswap<char>(a,b);
}
//函数模板作为函数参数
template<typename T1,typename T2>
int MySort(T1 *Array,T2 size);
{return 0;}
void main(){
int MyArray[]={11,22,44,22,55,2,3,5,7};
int size =sizeof(MyArray)/sizeof(*MyArray);
MySort<int,int>(MyArray,size);
}
int MySort(T1 *Array,T2 size){
if(Array==NULL){
return -1;
}
for(T2 i=0;i<size;i++){
for(T2 j=0;j<size;j++){
if(Array[i]<Array[j]){
myswap(Array[i],Array[j]);
}
}
}
}
C++编译器优先考虑普通函数
可以通过空模板实参列表的语法限定编译器只通过模板匹配
普通函数和模板函数的区别在于:
普通函数能过够隐式的进行类型转换,模板函数只能严格的按照定义来走。
eg:void myarray(T &a,T &b) 这意味着调用的时候函数参数类型必须是一致的。
类模板:
类模板用于实现类所需数据的类型参数化
类模板在表示如数组、表、图等数据结构显得特别重要,
这些数据结构的表示和算法不受所包含的元素类型的影响
继承中的类模板语法:
主要注意class B :public A<int>
以及B(int a,double x):A<int>(a){y=x;}
所有的类模板函数写在类的外部,在一个cpp中
//构造函数 没有问题
//普通函数 没有问题
//友元函数:用友元函数重载 << >>
// friend ostream& operator<< (ostream &out, Complex &c3) ;
//友元函数:友元函数不是实现函数重载(非 << >>)
//1)需要在类前增加 类的前置声明 函数的前置声明
template<typename T>
class Complex;
template<typename T>
Complex<T> mySub(Complex<T> &c1, Complex<T> &c2);
//2)类的内部声明 必须写成:
friend Complex<T> mySub <T> (Complex<T> &c1, Complex<T> &c2);
//3)友元函数实现 必须写成:
template
Complex mySub(Complex &c1, Complex &c2)
{
Complex tmp(c1.a - c2.a, c1.b-c2.b);
return tmp;
}
//4)友元函数调用 必须写成
Complex c4 = mySub(c1, c2);
cout<<c4;
结论:友元函数只用来进行 左移 友移操作符重载。
类模板中的static关键字
1) 请设计一个数组模板类( MyVector ),完成对int、char、Teacher类型元素的管理。
需求
设计:
类模板 构造函数 拷贝构造函数 << [] 重载=操作符
//MyVector.h
template <typename T>
class MyVector(){
friend ostream& operator<< (ostream &out,const MyVector<T> &obj);
public:
MyVector(int size=0);
MyVector(const MyVector &obj);
~MyVector;
public:
T &operator[](int index);
MyVector &operator=(const MyVector &obj);
private:
T *m_space;
int m_len;
}
//MyVector.cpp
template <typrname T>
MyVector<T>::MyVector(int size)
{
m_space=new T(size);
m_len=size;
}
template <typrname T>
MyVector<T>::MyVector(const MyVector &obj){
m_len=obj.m_len;
m_space=new T[m_len];
for(int i=0;i<m_len;i++)
{
m_space[i]=obj.m_space[i];
}
}
template <typrname T>
MyVector<T>::~MyVector(){
if(m_space!=NULL)
{
delete [] m_space;
m_space=NULL;
m_len=0;
}
}
MyVector<T>:: &operator[](int index)
{
return m_space[index];
}
MyVector<T>:: MyVecto &operator=(const MyVector &obj)
{
if(m_space!=NULL)
{
delete[] m_space;
m_space=NULL;
m_len=0;
}
m_len=obj.len;
m_space=new T[m_len];
for(int i=0;i<m_len;i++)
{
m_space[i]=obj[i];
}
return *this;
}
ostream& operator<<(ostream &out,const MyVector<T> &obj)
{
for(int i,i<obj.m_len;i++){
out<<obj.m_space[i]<<" "
}
}
class Teacher{
public:
Teacher(){
age=33;
m_p=new char[1];
strcpy(m_p,"");
}
Teacher(char *name,int age)
{
this->age=age;
m_p=new char[strlen(name)+1];//注意末尾\0
strcpy(m_p,name);
}
Teacher(const Teacher & obj)
{
this->age=obj.age;
m_p=new char [strlen(obj.m_p)+1];
strcpy(m_p,obj.m_p);
}
~Teacher(){
if(m_p!=NULL);
{
delete []m_p;
m_p=NULL
}
}
public:
friend ostream &operator<<(ostream &out,Teacher &obj){
out<<obj.age<<","<<obj.m_p<<endl;
return out;
}
Teacher &operator=(const Teacher &obj){
if(m_p!=NULL){
delete []m_p;
m_p=NULL;
age=33;
}
m_p=new char [strlen(obj.m_p)+1];
strcpy(m_p,obj.m_p);
return *this;
}
private:
int age;
char *pName;
}