我的C++实践(3):用多态机制来做设计

    多态polymorphism是指具有多种形态的情况,它能根据单一的标记关联不同的行为。多态是面向对象程序设计的基础。在面向对象程序设计中的多态是一种运行时的多态。C++中有两种多态,称为动多态(运行时多态)和静多态(编译时多态),而静多态主要通过模板来实现,宏也是实现静多态的一种途径。其实在做软件设计时静多态的威力也是非常强大的,只不过我们经常对它疏忽了而已。
    动多态的设计思想:对于相关的对象类型,确定它们之间的一个共同功能集,然后在基类中,把这些共同的功能声明为多个公共的虚函数接口。各个子类重写这些虚函数,以完成具体的功能。客户端的代码(操作函数)通过指向基类的引用或指针来操作这些对象,对虚函数的调用会自动绑定到你实际提供的子类对象上去。
    下面以几何对象的设计为例。对各种几何对象如圆、矩形、直线等,都有一些共同的操作,比如画出几何对象,有重心等,我们把这些接口抽象成虚函数放在所谓的抽象基类GeoObj中,具体的几何对象类则继承这个抽象基类。如下:

    客户端的使用如下:

    静多态的设计思想: 对于相关的对象类型,直接实现它们各自的定义,不需要基类。只是隐式地规定各个具体类的实现中相同功能的接口名要相同。客户端把操作这些对象的函数定义为模板,你需要操作什么类型的对象,直接对模板指定该类型实参即可(或通过实参演绎获得)。
    改写上面的设计,如下:

    两种多态设计范式的比较:
    (1)动多态的特点:通过继承实现、接口预先在基类中确定、是动态的(运行期绑定接口)。
    优点:能处理异类集合(容器中存储基类指针即可)、可执行代码比较小(只需一个多态函数)、可以完全编译而不需要发布源码。
    缺点:不能提前检查类型的安全性(如向容器中插入错误类型的对象)、性能低(有层层继承)、耦合性高(继承的耦合性高于组合)。
    (2)静多态的特点:通过模板实现(宏也是实现静多态的一种途径)、接口没有预先确定而只是隐式地规定、是静态的(编译期绑定接口)。
    优点:具体类可以只实现需要的接口、生成代码性能高(无需通过指针的间接调用,非虚函数具有更多的内联机会)、有更好的类型安全性(类型在编译期就进行检查)、耦合性低(各个类相互独立)、集合的元素类型不再局限于指针。
    缺点:不能处理异类集合、可执行代码比较大(代码膨胀)、模板库源码需要发布、对模板实参类型有约束(比如需要该类型实现了operator<)。
    现实中我们可以组合两种多态来做设计:从公共基类派生不同的子类,从而能够处理属于异类集合的不同对象。而需要操作具体某种类型的对象时,使用模板来实现。
    实际上,泛型程序设计依赖的就是静多态。C++中的一个泛型程序设计杰作就是STL。STL库中的设计思想是把对象的集合抽象为容器,把对对象的操作抽象为算法。算法和容器都是模板(即静多态方案),这样算法可以独立出来,而不是容器的成员函数。一个算法可以被多种容器使用。为了让容器能够使用算法,从容器中抽象出迭代器的概念,通过把容器的迭代器传给算法,就可以在容器上执行算法的行为。
    迭代器是泛型程序设计的粘合剂,它由容器提供并能被算法所使用。迭代器之所以能作粘合剂,是由于容器为迭代器提供了一些特定的接口,而算法所使用的正是这些接口。一般把这样的接口称为concept(即约束)。
    从原则上讲,我们也可以用动多态来实现STL,然而这肯定会带来很多的麻烦。与迭代器的概念相比,动多态的虚函数调用机制将会是一种重量级的实现机制,比如增加一层基于虚函数的接口层,通常这会对性能和效率产生很大的影响,有可能是几个数量级。可见,静多态也是一种威力非常强大的工具,只要应用得好,通过C++的模板,我们可以设计出抽象程度高、性能很好的软件组件。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值