读书笔记_Effective_C++_条款四十一:了解隐式接口和编译期多态
从本条款开始,就进入了全书的第七部分:模板与泛型编程。模板与泛型在C++中是非常重要的部分,还记得本书第一章时,把C++视为一个联邦,它由四个州政府组成,其中一个政府就是模板与泛型了。
本条款是一个介绍性质的条款,内容不难,只需要讲清楚两个概念就行了,即什么是隐式接口,什么是编译期多态。
隐式接口是相对于函数签名所代码的显式接口而言的。当我们看到一个函数签名(即函数声明),比如说:
string GetNameByStudentID(int StudentID);
我们就知道这个函数有一个整型的形参,返回值是string。
但隐式接口是由有效表达式组成的,考虑一个模板函数,像下面这样:
template <class T>
void TemplateFunction(T& w)
{
if(w.size() > ){…}
}
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具现化和函数重载解析发生于编译期。
读书笔记_Effective_C++_条款四十一:了解隐式接口和编译期多态的更多相关文章
- 读书笔记_Effective_C++_条款三十一:将文件间的编译依存关系降至最低(第三部分)
下面来谈谈书中的第二部分,用Interface Classes来降低编译的依赖.从上面也可以看出,避免重编的诀窍就是保持头文件(接口)不变化,而保持接口不变化的诀窍就是不在里面声明编译器需要知道大小的 ...
- Effective C++ -----条款41:了解隐式接口和编译期多态
classes和templates都支持接口(interface)和多态(polymorphism). 对classes而言接口是显式的(explicit),以函数签名为中心.多态则是通过virtua ...
- 读书笔记_Effective_C++_条款四十九:了解new_handler的行为
本章开始讨论内存分配的一些用法,C/C++内存分配采用new和delete.在new申请内存时,可能会遇到的一种情况就是,内存不够了,这时候会抛出out of memory的异常.有的时候,我们希望能 ...
- 读书笔记_Effective_C++_条款四十八:了解模板元编程
作为模板部分的结束节,本条款谈到了模板元编程,元编程本质上就是将运行期的代价转移到编译期,它利用template编译生成C++源码,举下面阶乘例子: template <int N> st ...
- 读书笔记_Effective_C++_条款四十七:请使用trait classes来表示类型信息
这一条款主要来讨论模板中迭代器的属性iterator_category,它可以通过类似于vector<int>::iterator::iterator_category的方式来取得. 到这 ...
- 读书笔记_Effective_C++_条款四十六:需要类型转换时请为模板定义非成员函数
这个条款可以看成是条款24的续集,我们先简单回顾一下条款24,它说了为什么类似于operator *这样的重载运算符要定义成非成员函数(是为了保证混合乘法2*SomeRational或者SomeRat ...
- 读书笔记_Effective_C++_条款四十五:运用成员函数模板接受所有兼容类型
比如有一个Base类和一个Derived类,像下面这样: class BaseClass {…}; class DerivedClass : public BaseClass {…}; 因为是父类与子 ...
- 读书笔记_Effective_C++_条款四十四:将与参数无关的代码抽离template
标题上说“将与参数无关的代码抽离template”,这里的参数既可以指类型,也可以是非类型,我们先来看看非类型的情况. 假定我们要为矩阵写一个类,这个矩阵的行列元素个数相等,是一个方阵,因而我们可以对 ...
- 读书笔记_Effective_C++_条款四十三:学习处理模板化基类的名称
背景是这样的,有两个不同的公司,然后想设计一个MessageSender,为这两个公司发送不同的消息,既支持明文发送SendClearText,也支持密文发送SendEncryptedText.一种思 ...
随机推荐
- SQL——系统函数
1) CASE CASE有两种使用形式:一种是简单的CASE函数,另一种是搜索型的CASE函数. [1]简单的 CASE 函数 Format: CASE input_expression WHEN w ...
- Linux下的NFS配置(转)
http://rubyer.me/blog/1682/ 遇到的问题: 1.reason given by server: Permission denied 在服务器的/etc/export配置文件中 ...
- javaweb学习总结(十五)——JSP基础语法
任何语言都有自己的语法,JAVA中有,JSP虽然是在JAVA上的一种应用,但是依然有其自己扩充的语法,而且在JSP中,所有的JAVA语句都可以使用. 一.JSP模版元素 JSP页面中的HTML内容称之 ...
- linux下安装小鹤双拼-鹤形
首先安装小小拼音.发现小小拼音真是一个良心软件 http://yong.dgod.net/ 进入下载页面.我是下载 解压版的 解压缩后.放在主目录里.可以改成.yong 隐藏起来 安装步骤(前人栽树, ...
- 地图源改变之后mxd文件打开很慢的问题
在使用ArcGIS开发电子地图程序时,有时候需要更换服务器地址,这时打开MXD文件就会非常慢,一直没有找到有效的方法,下面是从网上搜到的方法,还没有验证,下次再碰到这个问题的时候,验证一下: (以下方 ...
- 用eclipse建立servlet工程
1.打开eclipse,选择[文件]|[新建]|[项目] 2.选择[Tomcat Project]后单击下一步,输入项目名[TestTomcat],选择下一步,将[Can update contex ...
- C#中的Linq to Xml详解
这篇文章主要介绍了C#中的Linq to Xml详解,本文给出转换步骤以及大量实例,讲解了生成xml.查询并修改xml.监听xml事件.处理xml流等内容,需要的朋友可以参考下 一.生成Xml 为了能 ...
- liunx 套接字编程(Linux_C++)
网络中的进程是如何通信的? 在网络中进程之间进行通信的时候,那么每个通信的进程必须知道它要和哪个计算机上的哪个进程通信.否则通信无从谈起!在本地可以通过进程PID来唯一标识一个进程,但是在网络中这是行 ...
- Andriod Studio 开发环境安装和配置
Android Studio安装配置详细步骤(图文):http://www.2cto.com/kf/201604/500642.html第一次使用Android Studio时你应该知道的一切配置 : ...
- 【C++沉思录】句柄1
1.在[C++沉思录]代理类中,使用了代理类,存在问题: a.代理复制,每次创建一个副本,这个开销有可能很大 b.有些对象不能轻易创建副本,比如文件2.怎么解决这个问题? 使用引用计数句柄,对动态资源 ...