条款41:了解隐式接口与编译期多态(Understand implicit iterface and compile-time polymorhism)
类和对象:
显示接口(explicit interface): 即在源代码中可见, 可以在头文件内看到类的所有接口(由函数签名式函数名称参数类型返回值等)
运行期多态(runtime polymorphism):成员函数是virtual, 传入类的引用或指针时, 在运行时, 会自动匹配接口, 可能是基类的接口, 也可能是派生类的
模板(templates)和泛型编程(generic programming):
隐式接口(implicit interface):typename T, 在函数中, 所必须支持一组操作, 只有支持这些操作, 才能通过编译
编译期多态(compile-time polymorphism):通过模板(template)的实例化(instantiated)函数模板(function templates), 和重载类似, 都是在编译期绑定
在隐式接口中, 操作符等重载, 已经包含隐式类型转换
如果是程序可以通过编译, 无论是类还是模板, 都要需要通过多态满足接口的要求, 否则无法通过编译.
隐式接口并不基于函数签名式,而是有效表达式组成
template<typename T>
void doProcessing(T& w)
{
if (w.size()>10 && w != someNastyWidget)//看起来w必须提供名为size()函数并且支持运算符重载!=函数(但是这些都不需要满足)
{
T temp(w);
temp.normailze();
temp.swap(w);
}
}
T必须支持size()函数但是这个函数可能从base class 继承而来这个成员函数不需要返回一个整数值,甚至不需要返回一个数值类型他唯一要做的就是返回一个类型为X的对象而X对象加上int(10的类型)必须能够调用一个operator>.同时operator>也不必非得取得一个类型为x参数他也可以取得类型为Y参数,只要存在一个隐式转换将x转换为y
同样的T并不需要支持operator!= 因为这样也是可以得:operator!= 接受一个类型为X的对象和一个类型为Y的对象T可以被转化为X而someNastWidget的类型可被转化为Y这样就可以有效调用operator !=
隐式接口是仅仅有一组有效表达是组成表达式自身自身可能看起来复杂但是他们要求的约束条件相当直接而有明确
if (w.size()>10 && w != someNastyWidget) 必须与bool型兼容
请记住
@ class和template都支持接口和多态
@对于class而言接口是显示的以函数签名为中心,多态通过vitual函数发生于运行期间
@对于template而言接口是隐式的implicit基于有效表达式,多态则是通过template具现化和函数重载解析发生在编译期
条款42 了解typename的双重意义(Understand the two meaning o