Item 41:隐式接口与编译期多态 Effective C++笔记
来源:互联网 发布:添加字段sql 编辑:程序博客网 时间:2024/06/16 19:51
Item 41: Understand implicit interfaces and compile-time polymorphism.
面向对象设计中的类(class)考虑的是显式接口(explicit interface)和运行时多态, 而模板编程中的模板(template)考虑的是隐式接口(implicit interface)和编译期多态。
- 对类而言,显式接口是由函数签名表征的,运行时多态由虚函数实现;
- 对模板而言,隐式接口是由表达式的合法性表征的,编译期多态由模板初始化和函数重载的解析实现。
显式接口和运行时多态
一个类的显式接口是由public成员函数签名(包括函数名、参数类型、返回值类型等)、类型定义(typedef)、public数据成员构成的。
class Widget{public: Widget(); virtual ~Widget(); virtual size_t size() const; virtual void normalize(); void swap(Widget& other);};void doProcessing(Widget& w){ if(w.size() > 10 && w != someOne){ Widget tmp(w); tmp.normalize(); tmp.swap(w); }}
对于doProcesing
中的w
,我们可以知道:
w
应支持Widget
的接口,包括:normalize()
,swap()
等。这些接口在源码中是可以找到的,称为显式接口。Widget
有些成员函数是virtual
的,会表现出运行时多态:具体的被调用者会根据Widget
的动态类型而决定。
隐式接口和编译期多态
在模板和类属编程(generic programming)中这一点完全不同,在这里隐式接口和编译期多态更为重要:
template<typename T>void doProcessing(T& w){ if(w.size() > 10 && w!= someOne){ T tmp(w); tmp.normalize(); tmp.swap(w); }}
现在的doProcessing
是一个函数模板,其中的w
有所不同:
w
应支持的接口取决于模板中w
上的操作。比如:w
(类型T
)必须支持size
,normalize
,swap
方法;拷贝构造函数;不等运算符。 总之,这些表达式必须合法而且通过编译构成了w
应支持的接口。- 其中的
operator>
和operator!=
要调用成功可能需要实例化一些模板,而使用不同的模板参数实例化模板的过程就是编译期多态。
具体来讲,T
的隐式接口应满足:
- 必须包含一个返回值为整型的成员函数;
- 支持一个接受
T
类型的operator!=
函数。
但由于C++的运算符重载和隐式类型转换特性,上述两个条件都不需要满足。 首先size
可能是继承来的函数而非T
的成员函数,但它不需要返回一个int
,甚至不需要返回一个数字类型,返回类型也不需要定义operator>
。 它需要返回的类型X
只需满足:operator>
可以接受X
和int
。但operator>
的第一个参数类型可以不是X
,只要X
能隐式转换为它的第一个参数类型即可。 类似地,operator!=
接口也有极大的灵活性。
当你想到这些约束时可能真的会头大,但实践中比这些直观的多,接口只是由合法的表达式构成的。 例如下面的表达式看起来就很直观:
if (w.size() > 10 && w != someOne) ...
总之隐式接口和显式接口一样地真实存在,在编译时都会进行检查。正如你错误地使用显式接口会导致编译错一样, 对象不支持模板所要求的隐式接口也会导致编译错。
除非注明,本博客文章均为原创,转载请以链接形式标明本文地址: http://harttle.com/2015/09/08/effective-cpp-41.html
- Item 41:隐式接口与编译期多态 Effective C++笔记
- Effective C++ Item 41 了解隐式接口和编译期多态
- 《Effective C++》41: 了解隐式接口和编译期多态
- [翻译] Effective C++, 3rd Edition, Item 41: 理解 implicit interfaces(隐式接口)和 compile-time polymorphism(编译期多态)
- Effective C++:条款41:了解隐式接口和编译期多态
- 《Effective C++》读书笔记之item41:了解隐式接口和编译期多态
- Item 41 隐式接口和编译时多态
- 《Effective C#》Item 20:区分接口实现与虚函数重载
- 《Effective C#》Item 20:区分接口实现与虚函数重载
- 《Effective C#》Item 19:推荐在继承中使用接口
- 《Effective C#》Item 19:推荐在继承中使用接口
- 《Effective C#》Item 22:用事件定义对外接口
- 《Effective C#》 Item 27:避免使用 ICloneable接口
- 了解隐式接口和编译期的多态(Effective C++_41)
- Effective C++ Item 34 区分接口继承与实现继承
- more effective c++——Item M30 代理类(三)隐式类型转换与代理类
- <Effective Mordern C++>笔记:Item 2:Understand auto type deduction.
- <Effective Mordern C++>笔记:Item 3:Understand decltype .
- MVC - File download action
- 黑马程序员——Java线程技术
- 关于C语言中Implicit declaration of function ‘XXXX’ is invalid in C99警告
- [LeetCode 293] Flip Game
- RAID基础知识总结
- Item 41:隐式接口与编译期多态 Effective C++笔记
- *LeetCode-Flip Game II
- STL排序详解
- 迭代器
- Codevs P3007 智力大冲浪
- How to make Killer 1535 work in ubuntu
- [LeetCode294] Flip Game II
- iptables 限速网络
- Xampp+Xdebug+netbeans安装配置(php开发工具)