类模板与模板类(C++)

1、类模板

一个类模板(也称为类属类或类生成类)允许用户为类定义一种模式,使得类中的某些数据成员、默写成员函数的参数、某些成员函数的返回值,能够取任意类型(包括系统预定义的和用户自定义的)。如果一个类中数据成员的数据类型不能确定,或者是某个成员函数的参数或返回值的类型不能确定,就必须将此类声明为模板,它的存在不是代表一个具体的、实际的类,而是代表着一类类。

类模板的重点是模板。表示的是一个模板,专门用于产生类的模子。例如: 

 template   <typename   T>       
 class   Vector    
 { 
    …  
  };   

  使用这个Vector模板就可以产生很多的class(类),Vector<int>、Vector<char>、Vector<   Vector<int>   >、Vector<Shape*>……。     

 2、 模板类

模板类的重点是类。表示的是由一个模板生成而来的类。例如:  上面的Vector<int>、Vector<char>、……全是模板类。

3、类模板的定义

3.1首先要定义类,其格式为:

template <class T>
class foo
{
……
}

foo 为类名,在类定义体中,如采用通用数据类型的成员,函数参数的前面需加上T,其中通用类型T可以作为普通成员变量的类型,还可以作为const和static成员变量以及成员函数的参数和返回类型之用。例如:

template<class T>
class Test{
private:
    T n;
    const T i;
    static T cnt;
public:
    Test():i(0){}
    Test(T k);
    ~Test(){}
    void print();
    T operator+(T x);
};

3.2在类定义体外定义成员函数时,若此成员函数中有模板参数存在,则除了需要和一般类的体外定义成员函数一样的定义外,还需在函数体外进行模板声明,例如

template<class T>
void Test<T>::print(){
    std::cout<<"n="<<n<<std::endl;
    std::cout<<"i="<<i<<std::endl;
    std::cout<<"cnt="<<cnt<<std::endl; 
}

如果函数是以通用类型为返回类型,则要在函数名前的类名后缀上“<T>”。例如:

template<class T>
Test<T>::Test(T k):i(k){n=k;cnt++;}
template<class T>
T Test<T>::operator+(T x)
{
	return n + x;
}

3.3 在类定义体外初始化const成员和static成员变量的做法和普通类体外初始化const成员和static成员变量的做法基本上是一样的,唯一的区别是需在对模板进行声明,例如

template<class T>
int Test<T>::cnt=0;
template<class T>
Test<T>::Test(T k):i(k){n=k;cnt++;}

4、类模板的使用

4.1普通类继承模板类

template<class T>
class TBase
{
    T data;
……
};
class subClass:public TBase<int>
{
……
};

可能会出现以下情况:

template<class T>
class TBase
{
    T data;
……
};
class subClass:public TBase<subClass>
{
……
};

这种情况一般TBase类中放的是subClass的构造函数和析构函数,而subClass可以对构造函数和析构函数进行重载

4.2模板类继承普通类(较常见)

class Base{
……
};
template<class T>
class TsubClass:public Base{
T data;
……
};
4.3类模板继承类模板

template<class T>
class TBase{
T data1;
……
};
template<class T1,class T2>
class TsubClass:public TBase<T1>{
T2 data2;
……
};
4.4模板类继承模板参数给出的基类(继承哪个基类由模板参数决定)

#include<iostream>
using namespace std;
class BaseA
{
public:
    BaseA(){cout<<"BaseA founed"<<endl;}
};
class BaseB
{
public:
    BaseB(){cout<<"BaseB founed"<<endl;}
};
template<typename T, int rows>
class BaseC
{
private:
    T data;
public:
    BaseC():data(rows)
	{
        	cout<<"BaseC founed "<< data << endl;
	}
};
template<class T>
class TsubClass:public T
{
public:    
TsubClass():T(){cout<<"TsubClass founed"<<endl;}
};void main(){ 
	TsubClass<BaseA> x;// BaseA作为基类    
	TsubClass<BaseB> y;// BaseB作为基类    
	TsubClass<BaseC<int, 3> > ; // BaseC<int,3>作为基类
}
5、C++中易混淆的几个概念

5.1函数指针指针函数

函数指针的重点是指针,表示的是一个指向函数的指针。例如:

int (*pf)();

指针函数的重点是函数。表示的是一个函数,它的返回值是指针。例如: 

int*   fun(); 
5.2 数组指针与指针数组
数组指针的重点是指针。表示的是一个指针,它指向的是一个数组,例如:

int (*pa)[8];

指针数组的重点是数组。表示的是一个数组,它包含的元素是指针。例如;

int* ap[8];

5.3 函数模板与模板函数

函数模板的重点是模板。表示的是一个模板,专门用来生产函数。例如:

template   <typename   T>  
void   fun(T   a)   
{   
 ...
} 
在运用的时候,可以显式(explicitly)生产模板函数,fun<int>、fun<double>、fun<Shape*>……。也可以在使用的过程中由编译器进行模板参数推导,帮你隐式(implicitly)生成。   
  fun(6);//隐式生成fun<int>   
  fun(8.9);//隐式生成fun<double>   
  fun(‘a’);//   隐式生成fun<char>    
  Shape*   ps   =   new   Cirlcle;    
  fun(ps);//隐式生成fun<Shape*>

  模板函数的重点是函数。表示的是由一个模板生成而来的函数。例如:上面显式(explicitly)或者隐式(implicitly)生成的fun<int>、fun<Shape*>……都是模板函数。























  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值