上一篇博文“数组实现栈功能(C++练习记录)”中,栈只能接收char数据类型。通过类模板,使其能接收各种数据类型。
类模板:template<typename T>
类模板说明:
如同函数模板一样,使用类模板使用户可以为类定义一种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值能取任意类型。类模板是对一批仅仅成员数据类型不同的类的抽象,程序员只要为这一批类所组成的整个类家族创建一个类模板,给出一套程序代码,就可以用来生成多种具体的类,(这类可以看作是类模板的实例),从而大大提高编程的效率。
定义类模板的一般形式是:
template <类型名 参数名1,类型名参数名2,…>
class 类名
{
类声明体
};
例如,
template <typename T>
class MyStack
{
public:
MyStack(int size); //初始化栈空间
~MyStack();//回收栈空间内存
…
}
表示定义一个名为MyStack的类模板,其中带类型参数T。
在类模板的外部定义类成员函数的一般形式是:
template <类型名 参数名1,类型名参数名2,…>
函数返回值类型 类名<参数名 1 参数名 2,…>::成员函数名(形参表)
{
函数体
}
例如:
bool MyStack<T>::push(T elem)
{
if (stackFull())
{
return false;
}
m_pBuffer[m_itop] = elem;
m_itop++;
return true;
}
表示定义一个类模板MyStack的成员函数,函数名为push,形参elem的类型是T,函数返回bool值。
类模板是一个类家族的抽象,它只是对类的描述,编译程序不为类模板(包括成员函数定义)创建程序代码,但是通过对类模板的实例化可以生成一个具体的类以及该具体类的对象。
与函数模板不同的是:函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化必须由程序员在程序中显式地指定,
其实例化的一般形式是:
类名 <数据类型 1(或数据),数据类型 2(或数据)…> 对象名
例如,
MyStack<int> *pInt = new MyStack<int>(5);
具体代码实现:
注意事项:模板类的.cpp文件和.h文件不能分开编译
MyStack.h(在原程序基础上,变更为模板类而修改的代码用*****标识)
#ifndef MYSTACK_H
#define MYSTACK_H
/******************************/
/*模板栈实现 2017.03.08 by hyc*/
/******************************/
template <typename T> //模板类新增************
class MyStack
{
public:
MyStack(int size); //初始化栈空间
~MyStack();//回收栈空间内存
void clearStack();//清空栈
bool stackEmpty();//判空栈,若空返回true
bool stackFull();//判满栈,若满返回true
int stackLength();//栈中元素个数
bool push(T elem);//元素入栈,栈顶上升
bool pop(T &elem);//元素出栈,栈顶下降
void stackTraverse(bool isFromBottom);//遍历栈中元素 isFromBottom=1,从栈底遍历
private:
T *m_pBuffer;//栈空间指针 *************
int m_isize;//栈容量
int m_itop;//栈顶,也是栈中元素个数
};
//模板类不支持分开编译,拷贝原MyStack.cpp中内容
template <typename T> //***************
MyStack<T>::MyStack(int size) //MyStack<T>::
{
m_isize = size;
m_pBuffer = new T[size]; //***************
m_itop = 0;
}
template <typename T> //***************
MyStack<T>::~MyStack() //MyStack<T>::
{
delete[] m_pBuffer;
}
template <typename T> //***************
void MyStack<T>::clearStack()//MyStack<T>::
{
m_itop = 0;
}
template <typename T> //***************
bool MyStack<T>::stackEmpty()//MyStack<T>::
{
return 0 == m_itop ? true : false;
}
template <typename T> //***************
bool MyStack<T>::stackFull()//MyStack<T>::
{
return m_isize == m_itop ? true : false;
}
template <typename T> //***************
int MyStack<T>::stackLength()//MyStack<T>::
{
return m_itop;
}
template <typename T> //***************
bool MyStack<T>::push(T elem)//MyStack<T>::
{
if (stackFull())
{
return false;
}
m_pBuffer[m_itop] = elem;
m_itop++;
return true;
}
template <typename T> //***************
bool MyStack<T>::pop(T &elem)//MyStack<T>::
{
if (stackEmpty())
{
return false;
}
m_itop--;
elem = m_pBuffer[m_itop];
return true;
}
template <typename T> //***************
void MyStack<T>::stackTraverse(bool isFromBottom)//MyStack<T>::
{
if (isFromBottom)
{
for (int i = 0; i < m_itop; i++)
{
cout << m_pBuffer[i];
}
}
else
{
for (int i = m_itop - 1; i >= 0; i--)
{
cout << m_pBuffer[i];
}
}
}
#endif // !MYSTACK_H
demo.cpp
#include "MyStack.h"
#include <iostream>
using namespace std;
/******************************/
/*模板栈实现 2017.03.08 by hyc*/
/******************************/
int main(void)
{
MyStack<int> *pInt = new MyStack<int>(5);//MyStack<int>
pInt->push(1);
pInt->push(2);
pInt->stackTraverse(true);
MyStack<char> *pStack = new MyStack<char>(5);//MyStack<char>
pStack->push('h');//栈底
pStack->push('e');
pStack->push('l');
pStack->push('l');
pStack->push('o');//栈顶
if (pStack->stackFull()){
cout << "栈满" << endl;
}
pStack->stackTraverse(true);
cout << endl;
char ch;
pStack->pop(ch);
cout << ch << endl;
if (pStack->stackEmpty()){
cout << "栈空" << endl;
}
if (pStack->stackFull()){
cout << "栈满" << endl;
}
pStack->stackTraverse(false);
cout << pStack->stackLength() << endl;
pStack->clearStack();
if (pStack->stackEmpty()){
cout << "栈空" << endl;
}
delete pStack;
pStack = NULL;
system("pause");
return 0;
}
运行结果: