• 读书笔记_Effective_C++_条款四十一:了解隐式接口和编译期多态


    从本条款开始,就进入了全书的第七部分:模板与泛型编程。模板与泛型在C++中是非常重要的部分,还记得本书第一章时,把C++视为一个联邦,它由四个州政府组成,其中一个政府就是模板与泛型了。

    本条款是一个介绍性质的条款,内容不难,只需要讲清楚两个概念就行了,即什么是隐式接口,什么是编译期多态。

    隐式接口是相对于函数签名所代码的显式接口而言的。当我们看到一个函数签名(即函数声明),比如说:

     string GetNameByStudentID(int StudentID); 

    我们就知道这个函数有一个整型的形参,返回值是string。

    但隐式接口是由有效表达式组成的,考虑一个模板函数,像下面这样:

    1 template <class T>
    2 void TemplateFunction(T& w)
    3 {
    4     if(w.size() > 10){…}
    5 }

    T可以是int,可以double,也可以是自定义的类型。光看这个函数声明,我们不能确定T具体是什么,但我们知道,要想通过编译,T必须要支持size()这个函数。也就是说,T中一定要有这样的函数接口声明。

     ReturnValue size(); 

    当然返回值ReturnValue不一定是int了,只要它能支持operator > (ReturnValue, 10)这样的运算即可。这种由表达式推判出来的函数接口,称之为隐式接口。

    简言之,显式接口由函数签名式构成,隐式接口由有效的表达式组成。

    下面讨论编译期多态的问题,我们在讨论继承时就已经多次提到“运行时多态”了,它伴随着virtual关键字,本质是一个虚表和虚指针,在类对象构造时,将虚指针指向了特定的虚表,然后运行时就会根据虚表的内容进行函数调用。

    那么“编译期多态”又是什么呢,从字面上来看,它发生在编译阶段,实际上就是template <class T>这个T的替换,它可以被特化为int,或者double,或者用户自定义类型,这一切在编译期就可以决定下来T到底是什么,编译器会自动生成相应的代码(把T换成具体的类型),这就是编译期多态做的事情了,它的本质可以理解成自动生成特化类型版本,T可以被替换成不同的类型,比如同时存在int版本的swap与double版本的swap,形成函数重载。简言之,运行时多态是决定“哪一个virtual函数应该被绑定”,而编译期多态决定“哪一个重载函数应该被调用”。

    最后总结一下:

    1. class和template都支持接口与多态;

    2. 对classes而言,接口是显式的,以函数签名为中心。多态则是通过virtual函数发生于运行期;

    3. 对template参数而言,接口是隐式的,奠基于有效表达式。多态则是通过template具现化和函数重载解析发生于编译期。

  • 相关阅读:
    基于term vector深入探查数据
    oracle 行转列
    oracle 统计成绩
    最全最新个税计算公式---今天你税了吗?
    .net反混淆脱壳工具de4dot的使用
    使用ILSpy软件反编译.Net应用程序的方法及注意事项
    EmguCV使用Stitcher类来拼接图像
    从睡姿就可以看出你的性格,据说非常准,快存!
    分享几个.NET WinForm开源组件,纪念逐渐远去的WinForm。。。
    【转载】关于.NET下开源及商业图像处理(PSD)组件
  • 原文地址:https://www.cnblogs.com/jerry19880126/p/3620004.html
Copyright © 2020-2023  润新知