对于类模板的声明形式与相应的函数模板相同,只需要在相应类之前加上关键字template<typename T> ,后面直接接相应的类的定义,唯一不同的地方就是类中所有的类型统一采用T来表式。当程序编译时来根据具体的类型来类模板特化(就是生成能处理具体类型的类)。类型模板T的作用及所处的位置总结:1.相应函数形参类型 2.函数返回值类型 3.局部变量类型。c++中所有的类模板定义在相应的头文件中。只要引入相应的头文件,即可应用相应的类模板。对于自定义的类模板,我们也要相应的全部定义到头文件中(即:不能像以前那样头文件.h和源文件.cpp分开来定义,即类名加::二元域作用符来定义在类外定义的函数。否则编译的时候会报找不到相应的外部引用错误。这个是模板类的独特之处)
例:1.类模板测试--Stack.h
#ifndef STACK_H
#define STACK_Htemplate <typename T>
class Stack{
public:
Stack(int = 10);//构造函数默认值为10
~Stack(){//析构函数
delete[] ptr;//析构相应的对象
};
bool isEmpty(){
return top == -1;//即表示此堆栈是空的
}
bool isFull(){
return top == size -1;//即表示堆栈已满
}
bool push(const T &);//压入相应的元素
bool pop(T &);//弹出相应元素
private:
int size;
int top;
T *ptr;//指向具体内存的指针
};template <typename T>
Stack<T>::Stack( int i/*= 10*/ )//只能应用成员初始化列表器来初始化
:top(-1),size(i>0?i:10),ptr(new T[size])//初始化列表器
{
//empty
}template <typename T>
bool Stack<T>::push( const T &pushValue )
{
if(!isFull()){
ptr[++top] = pushValue;//压入相应的元素
return true;
}
return false;//这个地方就是为了用while时,放在条件里面来执行
}template <typename T>
bool Stack<T>::pop( T &popValue)
{
if(!isEmpty()){
popValue = ptr[top--];
return true;
}
return false;
}
#endif//此处类的所有函数实现都在头文件中进行,避免编译时出错。错误原因上面已有说明
-------------------------------------------------------------------------------------------------
2.主要的main.cpp函数
#include <iostream>
#include "Stack.h"
#include <string>
using namespace std;template<typename T> //模板函数来测试模板类
void testStack(Stack<T> &stack, T value, T incream, const string &stackName){
cout<<"element start push into: "<<stackName<<endl;
while(stack.push(value)){
cout<<value<<" ";
value += incream;
}
cout<<"\nthe stack "<<stackName<<" is full, element:"<<value<<" is not push"<<endl;
cout<<"\n\nelement start pop from: "<<stackName<<endl;
while(stack.pop(value)){
cout<<value<<" ";
}
cout<<"\nthe stack "<<stackName<<"is empty!"<<endl;
}int main(){
//Stack<int> a(5);//创建一个对象,对象维护一个int类型的堆栈
//int intValue = 1;
//cout<<"IntStack is pushed:"<<endl;
//while(a.push(intValue)){
// cout<<intValue<<" ";
// intValue += 1;//并不断的增加1
//}
//cout<<"\nIntStack is full,not push"<<endl;//cout<<"IntStack is pop!"<<endl;
//int popValue = 0;
//while(a.pop(popValue)){
// cout<<popValue<<" ";
//}
//cout<<"\nIntStack is empty!"<<endl;//cout<<endl<<endl<<endl;
//Stack<double> b;//创建一个对象,对象维护一个int类型的堆栈
//double doubleValue = 1.1;
//cout<<"DoubleStack is pushed:"<<endl;
//while(b.push(doubleValue)){
// cout<<doubleValue<<" ";
// doubleValue += 1.1;//并不断的增加1
//}
//cout<<"\nDoubleStack is full,not push"<<endl;//cout<<"DoubleStack is pop!"<<endl;
//double popDoubleValue;
//while(b.pop(popDoubleValue)){
// cout<<popDoubleValue<<" ";
//}
//cout<<"\nDoubleStack is empty!"<<endl;Stack<int> a(5);
Stack<double> b;//默认构造函数testStack(a, 1, 1,"stack_a");//模板函数来测试模板类
testStack(b, 1.1, 1.1, "stack_b");}
注:main()函数中的注释了的代码为相应的测试类模板测试代码,而最后面则采用了更高级的一种方式(即采用函数模板来测试相应的类模板。函数模板的定义在main()函数最上面(注意:函数模板不能定义在相应的main()函数中,否则会提示错误信息)。