多态及C++中的多态技术

多态(polymorphism)的字面意思就是多种形态。在程序设计领域,被广泛认可的一种定义是“将不同的特殊行为同单个泛化记号相关联的能力”,简单来说就是“通过单个标识支持不同行为的能力”或“单个接口,多种方法”。而在面向对象程序设计中,多态的一般表述是“同一消息(调用函数)发送给不同对象会产生不同的行为(即有不同的实现)”。例子如让动物叫,狗会吠叫,鸡则会啼叫。

1.维基百科中关于多态的解释和划分

在编程语言和类型论中,多态性是使用一个符号表示多个不同类型或者为不同类型的实体提供一个接口。
维基百科中主要提到了三种多态类型,特设多态(Ad hoc polymorphism)、参数式多态(Parametric polymorphism)和子类型多态(subtype polymorphism)。(https://en.wikipedia.org/wiki/Polymorphism_(computer_science))

  • 特设多态
    特设多态指能够接受不同类型的参数且依据参数的类型具有不同表现的多态型函数(也即函数重载或运算符重载)。
  • 参数式多态
    参数式多态允许函数或数据类型被泛型地编写,以便其能统一的处理值而不需要考虑值的类型。C++中的模板就是一种参数式多态。
  • 子类型多态
    子类型多态允许定义一个接受特定类型T对象的函数,但如果传入一个类型S的对象(类型S是类型T的子类),那么函数也能正确的工作,并具有不同的行为。

2.C++中的多态技术

C++中的多态主要分为两类:

  1. 动态多态(dynamic polymorphism)
    通过类继承和虚函数机制生效于运行期,也被称为运行时多态或子类型多态(Subtype polymorphism)。其可以优雅地处理异质对象集合,只要异质对象共同的基类定义了虚函数的接口。面向对象程序设计中指的多态就是动态多态。
  2. 静态多态(static polymorphism)
    通过模板也能实现不同特殊行为和单个泛化记号相关联,但这种关联在编译期就完成了(通过给模板参数指定类型),因此也被称作编译时多态。其可以用来实现类型安全、运行高效的同质对象集合操作。C++ STL采用模板来实现就是个例子。

此外,函数重载机制和带变量的宏也允许将不同的特殊行为和单个泛化记号相关联,可以看成多态现象(分别称作函数多态和带变量的宏多态)。然而,习惯上我们并不将它们展现出来的行为称为多态(或静态多态)。今天,当我们谈及多态时,如果没有明确所指,默认就是动态多态,而静态多态则是指基于模板的多态(也被称为参数式多态)。

详细解释和示例代码参见C++多态技术—静态多态和动态多态

C++中静态多态和动态多态的比较(https://www.cnblogs.com/Leo_wl/p/3667870.html):
静态多态
优点:

  • 由于静态多态是在编译期完成的,因此效率较高,编译器也可以进行优化;
  • 有很强的适配性和松耦合性,比如可以通过偏特化、全特化来处理特殊类型;
  • 最重要一点是静态多态通过模板编程为C++带来了泛型设计的概念,比如强大的STL库。

缺点:

  • 由于是模板来实现静态多态,因此模板的不足也就是静态多态的劣势,比如调试困难、编译耗时等
  • 不能够处理异质对象集合

动态多态
优点:

  • OO设计,是对客观世界的直觉认识;
  • 实现与接口分离,可复用
  • 处理同一继承体系下异质对象集合的强大威力

缺点:

  • 运行期绑定,导致一定程度的运行时开销;
  • 编译器无法对虚函数进行优化
  • 笨重的类继承体系,对接口的修改影响整个类层次;

两者不同点:

  • 本质不同,静态多态在编译期决定,由模板具现(实例化)完成,而动态多态在运行期决定,由继承、虚函数实现;
  • 动态多态中接口是显式的(在源码中能找到接口),以函数签名(函数名、参数、返回值类型)为中心,多态通过虚函数在运行期实现,静态多态中接口是隐式的,以有效表达式(模板类型参数声明)为中心,多态通过模板具现在编译期完成

两者相同点:

  • 都能够实现多态性,静态多态/编译期多态、动态多态/运行期多态;
  • 都能够使接口和实现相分离,一个是模板定义接口,类型参数定义实现,一个是基类虚函数定义接口,继承类负责实现;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值