C++ Templates:模板的多态威力

多态主要是通过继承和虚函数来实现的,这两个机制都是在运行期进行处理的,因此把这种多态称为动多态。平常所谈论的C++多态指的就是这种动多态。
模板也允许使用单一的泛型标记来关联不同的特定行为,这种借助于模板的关联是在编译器进行处理的,因此把这种多态称为静多态。

动多态:
动多态的设计思想主要在于:对于几个相关对象的类型,确定它们之间的一个共同功能集,然后在基类中,把这些共同的功能声明为多个虚函数接口。
基于这种设计方案的一个典型例子是:一个用于管理某些几何形状,并且能够以某种方式对这些形状进行修改的应用程序。
对于动多态而言,最引人注目的特性或许是处理异类容器的能力。
// 画出属于异类集合的GeoObjs对象
void drawElems (std::vector<GeoObj*> const& elems)
{
    for (unsigned i=0; i<elems.size(); ++i) {
        elems[i]->draw();  // 根据元素的类型来调用相应的 draw()
    }
}
int main()
{
    std::vector<GeoObj*> coll;  // 元素类型互异的集合
    coll.push_back(&l);         // insert line
    coll.push_back(&c);         // insert circle
    drawElems(coll);            // draw different kinds of GeoObjs
}

静多态:
可以把动多态中的myDraw()函数:
void myDraw (GeoObj const& obj)//GeoObj是一个抽象基类
{
    obj.draw();            // call draw() according to type of object
}
改写为:
template <typename GeoObj>
void myDraw (GeoObj const& obj)    //GeoObj是模板参数
{
    obj.draw();
}

使用动多态,在运行期只具有一个myDraw()函数
使用模板,则可能具有多个不同的函数,如myDraw<Line>()和myDraw<Circle>()。
不过,静多态不允许异类集合的处理,因为所有的类型都必须能够在编译器确定。

动多态和静多态:
通过继承实现的多态是绑定的和动态的:
    绑定的含义是:对于参与多态行为的类型,它们的接口是在公共基类的设计中就预先确定的
    动态的含义是:接口的绑定是在运行期完成的
通过模板实现的多态是非绑定的和静态的:
    非绑定的含义是:对于参与多态行为的类型,它们的接口是没有预先确定的
    静态的含义是:接口的绑定在编译器完成的

各自的优点:
动多态:
能够优雅地处理异类集合
可执行代码的大小通常比较小(因为只需要一个多态函数,但对于静多态而言,为了处理不同的类型,必须生成多个不同的模板实例)
可以对代码进行完全编译;因此并不需要发布实现源码(但是,分发模板库通常都需要同时分发模板实现的源代码)
静多态:
可以很容易地实现内建类型的集合
所生成的代码效率通常比较高(因为并不存在通过指针的间接调用,而且,可以进行演绎的非虚拟函数具有更多的内联机会)
对于只提供部分接口的具体类型,如果在应用程序中只是使用到这一部分接口,那么也可以使用该具体类型,而不必在乎该类型是否提供其他部分的接口
 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值