条款41:了解隐式接口和编译器多态
在学习该条款之前,我们先来介绍一下如下定义:
- 隐式接口:通过表达式推断出来的函数接口称为隐式接口;
class Widget;
void doProcessing(Widget& w){
if(w.size()>10&&w!=someNastyWidget){
Widget temp(w);
temp.normalize();
temp.swap(w);
}
}
这里我们的隐式接口表示Widget类型必须支持size()函数,同时可以支持operator>和operator!=运算符,这些就是其隐式接口;
- 显示接口:通过函数声明的接口则是显示接口。
- 编译器多态:很显然,这种多态发生在编译阶段,实际上就是template <class
T>的替换,可以被具现化(initialized)成int,double或者用户自定义类型,主要负责编译期间哪个重载函数被调用,例如有int swap(int*,int*)和double swap(double*,double*),编译器确定调用那个重载函数; - 运行期多态:哪一个virtual函数应该被绑定。
加诸于template参数身上的隐式接口,就像加诸于class身上的显示接口一样真是,而且两者都在编译期间完成检查,就像你无法用一种“与class提供之显示接口矛盾”的方式来使用对象那个,你也无法在template中使用“不支持template所要求的隐式接口”对象。
总结:
1)class和template都支持接口(interfaces)和多态(polymorphism);
2)对classes而言接口是显示的(explicit),以函数签名为中心,运行期多态通过virtual函数发生于运行期;
3)对template参数而言,接口是隐式的(implicit),奠基于有效表达式,编译器多态则是通过template具现化和函数重载解析发生与编译期。