官术网_书友最值得收藏!

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"
}
主站蜘蛛池模板: 普兰店市| 紫金县| 天等县| 馆陶县| 左贡县| 利川市| 扬州市| 武威市| 鄄城县| 紫云| 新宁县| 凯里市| 汉源县| 乌海市| 娄底市| 任丘市| 宁津县| 昭平县| 民和| 东阳市| 靖安县| 都江堰市| 探索| 富裕县| 沂南县| 奉新县| 高淳县| 隆安县| 邻水| 渝北区| 沁阳市| 龙南县| 大冶市| 富阳市| 山西省| 长阳| 民勤县| 湘阴县| 横峰县| 三河市| 大埔县|