
条款41:了解隐式接口和编译期多态
发布日期:2021-05-07 03:15:46
浏览次数:23
分类:精选文章
本文共 1946 字,大约阅读时间需要 6 分钟。
1、显式接口和运行期多态
(1)简介
面向对象编程总是以显式接口和运行期多态来解决问题。例如:
class Widget{ public: Widget(); virtual ~Widget(); virtual std::size_t size() const; virtual void normalize(); virtual swap(Widget& other); }; void doProcessing(Widget& w) { if (w.size() > 10 && w != someNastyWidget){ Widget temp(w); temp.normalize(); temp.swap(w); } }
(2)所谓的显式接口
由于w的类型被声明为Widget,因此w需要Widget接口,并且我们可以在源码中找到这个接口,看到源码的样子,所以称为是显式接口。
(3)所谓的运行期多态
由于Widget的某些函数是虚函数,因此w的某些函数在运行期间才可以根据w的类型动态调用相关版本的函数,这就是所谓的运行期多态。
2、 隐式接口和编译期多态
(1)泛型编程与面向对象编程的不同之处
在泛型编程中,显式接口与运行期多态仍有使用,但是其主要应用的是隐式接口和编译期多态。
例如将刚才的函数改为函数模板:
templatevoid doProcessing(T& w) { if (w.size() > 10 && w != someNastyWidget){ T temp(w); temp.normalize(); temp.swap(w); } }
(2)所谓的隐式接口
void doProcessing(T& w) //w需要支持的操作都是隐式接口
这个时候w发生了什么样的改变呢?
w所需要支持的接口需要当函数模板具现化时执行于w身上的操作决定(执行了什么操作,说明w一定需要支持这些接口),例子中w使用了size、normalize、swap函数、copy构造函数、不等比较。并且if语句中还有一个长表达式。这所有的函数与长表达式便是T必须支持的一组隐式接口(其实就是w需要被约束的东西)。(w.size() > 10 && w != someNastyWidget)(3)所谓的编译期多态
使用到w的任何函数调用,都可能会造成模板具现化,这样的函数具现化发生在编译期,而且不同的模板参数导致不同的模板函数,这就是所谓的编译期多态。
3、隐式接口和显式接口的不同之处
通常显式接口是由函数的签名式(函数名称、参数类型、返回类型)构成。
但是隐式接口不是基于签名式的,而是由有效表达式组成。
例如:templatevoid doProcess(T& w) { if(w.size()>10&&w!=someNastyWidget) ……}
w.size()>10&&w!=someNastyWidget//这就是所谓的隐式接口,是一组有效表达式。
w的隐式接口似乎有下述的约束:
- 提供size()函数,返回整数值
- 支持!= 操作符重载,用来比较两个T对象
但是实际上由于操作符重载的关系,隐式接口实际上不需要满足这两个约束。原因如下:
- w可能继承自base class的size 函数,因此不需要有size函数
- 并且size函数也没必要返回一个整数,只要它能够返回一个类型为X的对象,并且X和10 能够调用> 符号函数即可。
- ‘>’不需要非得是对象X的成员函数(可以是全局的一个函数。)
- 再退一步,并且符号函数>也并不是非得取得一个X对象和一个10才可以,只要X对象能隐式转换为size函数能够接受的对象即可。
4、最后
总之,隐式接口就是一组表达式,不管中间过程怎么样,只要最终的结果是一个满足类似于上述if语句中的表达式应该有的结果就行,比如if的条件表达式应该是bool类型的,只要括号里的表达式最终的结果是bool类型即可。表达式中间的接口可能并不需要w去支持。这些就是所谓的隐式接口。
普通的调用的函数也是对于w的约束,因此也是一个隐式接口。长表达式也是隐式接口,但是由于操作符重载的关系,可能w并不需要满足其中的一些约束。
无论是隐式接口还是显式子接口,都是在编译期完成检查,如果传递一个不支持所谓的隐式接口的模板参数给函数模板,同样的不能够通过编译。
发表评论
最新留言
哈哈,博客排版真的漂亮呢~
[***.90.31.176]2025年04月01日 23时55分53秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
《你当像鸟飞往你的山》总结
2021-05-09
《我是猫》总结
2021-05-09
《抗糖化书》总结
2021-05-09
apache虚拟主机配置
2021-05-09
PHP官方网站及PHP手册
2021-05-09
mcrypt加密以及解密过程
2021-05-09
go等待N个线程完成操作总结
2021-05-09
ReactJs入门教程-精华版
2021-05-09
Python 之网络式编程
2021-05-09
MySql5.5安装步骤及MySql_Front视图配置
2021-05-09
Java内存模型(JMM)
2021-05-09
AQS相关
2021-05-09
WCF学习之旅—第三个示例之一(二十七)
2021-05-09
java ThreadPoolExecutor初探
2021-05-09
快速指数算法
2021-05-09
python去除字符串中的特殊字符(爬虫存储数据时会遇到不能作为文件名的字符串)
2021-05-09
SpringCloud微服务(03):Hystrix组件,实现服务熔断
2021-05-09
Spring 框架基础(01):核心组件总结,基础环境搭建
2021-05-09