Jerry's Blog

Recording what I learned everyday

View on GitHub


3 January 2021

cpp -- Templates, Vectors, and Stacks(1)

by Jerry Zhang

Templates Basics

可以定义一个函数的模板,template<typename T>

template<typename T>
T maxValue(T value1, T value2)
{
  if (value1 > value2)
    return value1;
  else
    return value2;
}

调用这个函数的时候,可以传入int, double, char, 或者string。

==注意!如果要比较string,不能直接用maxValue(“NBC”, “ABC”)。因为这样传进去的是C-strings,比较的是地址。正确的写法是:maxValue(string(“NBC”), string(“ABC”))==

前面的函数定义是pass by value,当然也可以定义成pass by reference:

template<typename T>
T maxValue(const T& value1, const T& value2)
{
  if (value1 > value2)
    return value1;
  else
    return value2;
}

这个template关键字是写在每个函数上面的。定义多少个函数就要写多少遍。

Class Templates

也可以用泛型定义一个class。比如:

#ifndef STACK_H
#define STACK_H

template<typename T>
class Stack
{
public:
  Stack();
  bool empty() const;
  T peek() const;
  void push(T value);
  T pop();
  int getSize() const;

private:
  T elements[100];
  int size;
};

template<typename T>
Stack<T>::Stack()
{
  size = 0;
}

template<typename T>
bool Stack<T>::empty() const
{
  return (size == 0);
}

template<typename T>
T Stack<T>::peek() const
{
  return elements[size - 1];
}

template<typename T>
void Stack<T>::push(T value)
{
  elements[size++] = value;
}

template<typename T>
T Stack<T>::pop()
{
  return elements[--size];
}

template<typename T>
int Stack<T>::getSize() const
{
  return size;
}

#endif

==注意:这个类的定义和实现都放在了同一个文件里,是因为有些编译器无法识别分开的。==

Improving the Stack Class

如果想改成可变长度的数组,就要用到指针,也就是动态数组。不要忘记delete掉指针。

#ifndef IMPROVEDSTACK_H
#define IMPROVEDSTACK_H

template<typename T>
class Stack
{
public:
  Stack();
  Stack(const Stack&);
  ~Stack();
  bool empty() const;
  T peek() const;
  void push(T value);
  T pop();
  int getSize() const;

private:
  T* elements;
  int size;
  int capacity;
  void ensureCapacity();
};

template<typename T>
Stack<T>::Stack(): size(0), capacity(16)
{
  elements = new T[capacity];
}

template<typename T>
Stack<T>::Stack(const Stack& stack)
{
  elements = new T[stack.capacity];
  size = stack.size;
  capacity = stack.capacity;
  for (int i = 0; i < size; i++)
  {
    elements[i] = stack.elements[i];
  }
}

template<typename T>
Stack<T>::~Stack()
{
  delete [] elements;
}

template<typename T>
bool Stack<T>::empty() const
{
  return (size == 0);
}

template<typename T>
T Stack<T>::peek() const
{
  return elements[size - 1];
}

template<typename T>
void Stack<T>::push(T value)
{
  ensureCapacity();
  elements[size++] = value;
}

template<typename T>
void Stack<T>::ensureCapacity()
{
  if (size >= capacity)
  {
    T* old = elements;
    capacity = 2 * size;
    elements = new T[size * 2];

    for (int i = 0; i < size; i++)
      elements[i] = old[i];

    delete [] old;
  }
}

template<typename T>
T Stack<T>::pop() 
{
  return elements[--size];
}

template<typename T>
int Stack<T>::getSize() const
{
  return size;
}

#endif

tags: cpp