1. classes 和 templates 都支持接口(interfaces)和多态(polymorphism) 。
2. 对 classes 而言接口是显式的(explicit),以函数签名(也就是函数名称、参数类型、返回类型)为中心。多态则是通过 virtual 函数发生于运行期。
3. 对 template 参数而言,接口是隐式的(implicit),奠基于有效表达式。多态则是通过 template 具现化和函数重载解析(function overloading resolution)发生于编译期。
显式接口和运行期多态
void doProcessing(Widget& w)
{
if(w.size() > 10 && w != someNastyWidget) {
Widget temp(w);
temp.normalize();
temp.swap(w);
}
}
- w 的类型被声明为 Widget,我们可以在源码中找出 Widget 提供的接口(例如在 Widget 的 .h 文件中),所以称此为显式接口(explicit interface),也就是它在源码中明确可见。
- 由于 Widget 的某些成员函数是 virtual,w 对那些函数的调用将表现出运行期多态(runtime polymorphism),也就是说将于运行期根据 w 的动态类型决定究竟调用哪一个函数。
隐式接口和编译期多态
template<typename T>
void doProcessing(T& w)
{
if(w.size() > 10 && w != someNastyWidget) {
T temp(w);
temp.normalize();
temp.swap(w);
}
}
- w 必须支持哪一种接口是由 template 中执行于 w 身上的操作来决定的。目前看来,本例中 w 的类型必须支持 size、normalize 和 swap 成员函数、copy 构造函数(用来建立 temp)、不等比较(用来比较 someNastyWidget)。这一组表达式便是 T 必须支持的一组隐式接口(implicit interface)。
- 凡涉及 w 的任何函数调用,例如 operator> 和 operator!=,有可能造成 template 具现化,使这些调用得以成功。这样的具现行为发生在编译期。“以不同的 template 参数具现化 function templates”会导致调用不同的函数,这便是所谓的编译期多态(compile-time polymorphism)。
评论区