
Templates
Suppose that we need a stack of integers in an application. We could use the one in the previous section. Then maybe we also need a stack of characters, and maybe another one of car objects. It would certainly be a waste of time to repeat the coding for each type of stack. Instead, we can write a template
class with generic types. When we create an object of the class, we specify the type of the stack. The condition is that the methods, functions, and operators used are defined on the involved types; otherwise, a linking error will occur. Due to linking issues, both the definition of the class and the methods shall be included in the header file. The following is a template version of the stack.
TemplateCell.h
template <typename Type> class Cell { public: Cell(Type value, Cell<Type>* pNextCell); Type& Value() {return m_value;} const Type Value() const {return m_value;} Cell<Type>*& Next() {return m_pNextCell;} const Cell<Type>* Next() const {return m_pNextCell;} private: Type m_value; Cell<Type>* m_pNextCell; }; template <typename Type> Cell<Type>::Cell(Type value, Cell<Type>* pNextCell) :m_value(value), m_pNextCell(pNextCell) { // Empty. }
TemplateStack.h
template <typename Type> class TemplateStack { public: TemplateStack(); ~TemplateStack(); void Push(Type value); void Pop(); Type Top(); bool IsEmpty(); private: Cell<Type>* m_pFirstCell; }; template <typename Type> TemplateStack<Type>::TemplateStack() :m_pFirstCell(NULL) { // Empty. } template <typename Type> TemplateStack<Type>::~TemplateStack() { Cell<Type>* pCurrCell = m_pFirstCell; while (pCurrCell != NULL) { Cell<Type>* pRemoveCell = pCurrCell; pCurrCell = pCurrCell->Next(); delete pRemoveCell; } } template <typename Type> void TemplateStack<Type>::Push(Type value) { Cell<Type>* pNewCell = new Cell<Type>(value,m_pFirstCell); assert(pNewCell != NULL); m_pFirstCell = pNewCell; } template <typename Type> void TemplateStack<Type>::Pop() { assert(m_pFirstCell != NULL); Cell<Type>* pRemoveCell = m_pFirstCell; m_pFirstCell = m_pFirstCell->Next(); delete pRemoveCell; } template <typename Type> Type TemplateStack<Type>::Top() { assert(m_pFirstCell != NULL); return m_pFirstCell->Value(); } template <typename Type> bool TemplateStack<Type>::IsEmpty() { return m_pFirstCell == NULL; }
Finally, there is also a freestanding template function, in which case we do not have to state the type of the parameters before we call the function.
Main.cpp
#include <iostream> #include <string> using namespace std; #include <cstdlib> #include <cassert> #include "TemplateCell.h" #include "TemplateStack.h" template <typename Type> Type Min(Type value1, Type value2) { return (value1 < value2) ? value1 : value2; } void main() { TemplateStack<int> intStack; intStack.Push(1); intStack.Push(2); intStack.Push(3); TemplateStack<double> doubleStack; doubleStack.Push(1.2); doubleStack.Push(2.3); doubleStack.Push(3.4); int i1 = 2, i2 = 2; cout << Min(i1, i2) << endl; // 2 string s1 = "abc", s2 = "def"; cout << Min(s1, s2) << endl; // "def" }