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