模板参数

默认类型参数

函数参数可以设定一个默认值,我们现在可以对类模板的类型参数设定一个默认类型。

指定泛型Stack的默认类型参数为 int

template<typename T = int>
class Stack{
...
};

当我们这样定义一个对象时:

Stack<> stack;

使用默认的方式,或者说隐式的方式,实例化了一个stack对象。

这样的好处是:指定默认类型之后,使用者就没必要去写了。

非类型参数

在模板前缀中使用非类型参数。
实例化模板时,非类型实参应该是对象。
如下:

template<typename T, int capacity>
class Stack {
...
private:
T elements[capacity];
int size;
};
Stack<char, 100> charStack;

如同std里面的array的初始化:​​std::array<int,100>;​​ 除了基本数据类型外,非类型实参是对象的时候是这样的;

template<typename T, Color c>
class Label {
...
};
Color color(0,0,255);
Label<char,color> label;

注意,参数默认值必须是在最右边,当然我们也可以全部定义一个默认值,这样就不会有问题了。
注意模板成员函数的声明也需要进行修改。
就是这样:

//泛型化
template <typename T = char,int N = 100>
//编写StackOfIntegers类
class Stack {
private:
T elements[N];
int size{ 0 };
public:
bool empty();
T peek();
T push(T value);
T pop();
int getSize();
Stack();
};
template <typename T, int N>
Stack<T,N>::Stack() {
size = 0;
for (auto& i : elements) {
i = 0;
}
}

模板继承

关于模板继承的几个原则:

1、普通类可从类模板实例继承。一个模板实例化之后就是一个类了,类与类之间可以继承。
2、模板可从普通类继承
3、类模板可继承类模板

也就是说,一个类是不可以从一个模板继承的,其他的三种组合方式都是可以的。
【C++基础】模板参数与模板继承_类模板

何时何地使用模板

使用别人写好的模板库时
对不同类型的数据做类似处理 (算法、容器、遍历等)

OOP or GP

泛型编程在C++中广泛使用,经常可以取代面向对象编程。
几乎整个C++标准库都依赖于泛型编程。
在C++标准库较少使用继承和运行时多态。异常、字符串和IO流中使用了较多的继承。