Item 41 隐式接口和编译时多态

OOP编程与类属编程(generic programming)的一大区别:
1> OOP使用显式的接口和运行时多态
2> 类属编程使用隐式接口和编译时多态

 

void doProcessing(Widget& w) { if (w.size() > 10 && w != someNastyWidget) { Widget temp(w); temp.normalize(); temp.swap(w); } }

 

当你看到上面的代码时,你能在某个文件里找到下面的声明:

 

class Widget { public: Widget(); virtual ~Widget(); virtual std::size_t size() const; virtual void normalize(); void swap(Widget& other); // see Item 25 ... };

 

Widget支持什么函数一目了然,此之谓“显式接口”。许多函数以virtual打头,需在运行时绑定到某个实现上,此之谓“运行时多态”。

下面修改一下doProcessing函数:

 

template<typename T> void doProcessing(T& w) { if (w.size() > 10 && w != someNastyWidget) { T temp(w); temp.normalize(); temp.swap(w); } }

 

可以看出,T肯定支持的有size、normalize、swap、copy ctor函数,同时也有很多不确定的因素:
1> 比如size可在T中定义,也可能继承自父类。
2> size的返回值也不见得就是int。只要其返回的类型支持operator>即可。
3> operator!=可能存在,不存在的话也可以。只要T可以转型为支持该操作符的类型即可。
...
这些不确定的因素,都是隐含的,此之谓隐式接口。有别于OOP中函数签名极为明确的特质。

因为要调用doProcessing函数,就要实例化该模板函数,那么就要确定T是什么类型。
这些不确定的因素使得doProcessing函数有了多态的性质,而所有这些不确定因素要在编译时确定下来。
所以,谓之为“编译时多态”。有别于虚函数要在运行时确定的特质。

你可能感兴趣的:(编程,oop,Class)