条款41:了解隐式接口和编译期多态

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)泛型编程与面向对象编程的不同之处

在泛型编程中,显式接口与运行期多态仍有使用,但是其主要应用的是隐式接口和编译期多态。

例如将刚才的函数改为函数模板:

template<typename T>
void 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、隐式接口和显式接口的不同之处

通常显式接口是由函数的签名式(函数名称、参数类型、返回类型)构成。

但是隐式接口不是基于签名式的,而是由有效表达式组成。
例如:

template<typename T>
void 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并不需要满足其中的一些约束。

无论是隐式接口还是显式子接口,都是在编译期完成检查,如果传递一个不支持所谓的隐式接口的模板参数给函数模板,同样的不能够通过编译。

原文地址:https://www.cnblogs.com/lasnitch/p/12236460.html

时间: 2024-11-10 07:54:15

条款41:了解隐式接口和编译期多态的相关文章

Effective C++ 条款41 了解隐式接口和编译期多态

1. 面向对象编程通常以显式接口(类中的函数原型)和运行时多态(虚函数和RTTI)解决问题,但在Templates及泛型编程的世界,尽管显式接口和运行时多态仍然存在,但隐式接口和编译时多态的重要性却明显提升. 2.通常显式接口由函数签名式构成,而隐式借口并不基于函数声明式,而是有有效表达式组成. 所谓泛型编程中的隐式接口,指的是类型参数在函数模板或类模板中的成员函数内部所涉及的操作.也就是说类型参数必须支持函数模板内部所进行的操作,比如operator>,operator!=等,而对于不同类型,

Effective C++ Item 41 了解隐式接口和编译期多态

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:class 和 templates 都支持接口和多态. 对 classes 而言接口是显式的,以函数签名为中心.多态则是通过 virtual 函数发生于运行期 对 templates 参数而言,接口是隐式的,奠基于有效表达式.多态则是通过 templates 具体化和函数重载解析(function overloading resolution)发生于编译期. 示例1:显式接口和运行期

读书笔记 effective c++ Item 41 理解隐式接口和编译期多态

1. 显示接口和运行时多态 面向对象编程的世界围绕着显式接口和运行时多态.举个例子,考虑下面的类(无意义的类), 1 class Widget { 2 public: 3 Widget(); 4 virtual ~Widget(); 5 6 virtual std::size_t size() const; 7 virtual void normalize(); 8 9 void swap(Widget& other); // see Item 25 10 11 ... 12 13 }; 考虑下

Effective C++ -----条款41:了解隐式接口和编译期多态

classes和templates都支持接口(interface)和多态(polymorphism). 对classes而言接口是显式的(explicit),以函数签名为中心.多态则是通过virtual函数发生于运行期. 对template参数而言,接口是隐式的(implicit),奠基于有效表达式.多态则是通过template具现化和函数重载解析(function overloading resolution)发生于编译期.

显示接口和隐式接口的区别:

一.新建一个接口类 using System; using System.Collections.Generic; using System.Linq; using System.Web; /// <summary> /// InterF 的摘要说明 /// </summary> public class InterF { public interface hide { string show(); } public interface display { string show(

C# - 接口_隐式接口实现

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace 接口_隐式接口实现 7 { 8 // 定义接口1 : IChineseGreeting 9 interface IChineseGreeting 10 { 11 void SayHello(); 12 } 13 14 // 定义接口2 : IAmericanGreeting 15 i

008.在C#中,显式接口VS隐式接口

原文http://www.codeproject.com/Articles/1000374/Explicit-Interface-VS-Implicit-Interface-in-Csharp (Aty表示本人) 介绍 什么是显式和隐式接口 什么时候需要显式接口 更简洁的方法(ISP:接口隔离原则) 显式接口更多 结论 介绍 文章将讨论下显式接口,讨论它们与隐式接口的区别,以及为什么应该避免使用. 什么是显式和隐式接口 C#中有两种方式来实现接口:显式和隐式 定义如下接口: 当我们隐式的实现该接

转载:C++编译期多态与运行期多态

前言 今日的C++不再是个单纯的“带类的C”语言,它已经发展成为一个多种次语言所组成的语言集合,其中泛型编程与基于它的STL是C++发展中最为出 彩的那部分.在面向对象C++编程中,多态是OO三大特性之一,这种多态称为运行期多态,也称为动态多态:在泛型编程中,多态基于template(模 板)的具现化与函数的重载解析,这种多态在编译期进行,因此称为编译期多态或静态多态.在本文中,我们将了解: 什么是运行期多态 什么是编译期多态 它们的优缺点在哪 回到顶部 运行期多态 运行期多态的设计思想要归结到

编译期多态和运行时多态

前言 今日的C++不再是个单纯的"带类的C"语言,它已经发展成为一个多种次语言所组成的语言集合,其中泛型编程与基于它的STL是C++发展中最为出彩的那部分.在面向对象C++编程中,多态是OO三大特性之一,这种多态称为运行期多态,也称为动态多态:在泛型编程中,多态基于template(模板)的具现化与函数的重载解析,这种多态在编译期进行,因此称为编译期多态或静态多态.在本文中,我们将了解: 1.什么是运行期多态   2.什么是编译期多态   3.它们的优缺点 运行期多态 运行期多态的设计