Templates的静态多态性

一、动态多态性与静态多态性

所谓多态,是一种「以单一泛化记号(generic notation)表述多种特定行为」的能力。多态是面向对象编程思维模型的基石,C++主要通过class的继承和虚拟函数(virtual functions)支持多态。由于这些机制(全部或部份)生效于执行期,所以称为动态多型(dynamic polymorphism)。谈论C++ 多型时,所指的通常便是动态多态性。然而 templates 也允许我们以单一泛化记号表述多种特定行为,只不过一般发生在编译期,因此称为静态多型(static polymorphism)。

二、动态多态性

在彼此相关的 object types 之间确认一套共通能力,并将其声明为某共通基础类别(common base class)的一套虚拟函数接口。

1、以Qt界面绘图中item举例,示例代码如下

class GeoObj {
public:
	// 绘制几何对象:
	virtual void draw() const = 0;
	// 传回几何对象的重心(center of gravity):
	virtual Coord center_of_gravity() const = 0;
	//...
};

class Circle : public GeoObj {
public:
	virtual void draw() const;
	virtual Coord center_of_gravity() const;
	//...
};

class Line : public GeoObj {
public:
	virtual void draw() const;
	virtual Coord center_of_gravity() const;
	//...
};

class Rectangle : public GeoObj {
public:
	virtual void draw() const;
	virtual Coord center_of_gravity() const;
	//...
};

2、类UML图如下:

每一个针对特定几何对象而设计的具象类别(concrete class)都衍生自 GeoObj
请添加图片描述

3、动态多态实现或发生

//绘制
void myDraw(const GeoObj* obj)
{
	obj->draw();	// 根据对象指针具体所指对象的类型调用 draw()
}
// 处理两个 GeoObjs重心之间的距离
Coord distance(const GeoObj* x1, const GeoObj* x2)
{
	Coord c = x1->center_of_gravity() - x2->center_of_gravity(); return c.abs();	// 传回坐标绝对值
}

4、示例总结

上述程序的关键性多型接口元素是draw()和center_of_gravity(),两者都是虚拟函数。当操作:如果对一个 Line对象指针调用 myDraw(),函数内的 obj->draw()就调用 Line::draw();对 Circle对象指针调用的则是 Circle::draw()。对 distance()而言也是同样道理。

三、静态多态性

Templates 也可以用来实作多态,然而它们并不倚赖「分解及抽取 base classes 共通行为」。

1、仍然以Qt界面绘图中item举例,示例代码如下

class Circle {
public:
	void draw() const;
	Coord center_of_gravity() const;
	//...
};

class Line {
public:
	void draw() const;
	Coord center_of_gravity() const;
	//...
};

class Rectangle {
public:
	void draw() const;
	Coord center_of_gravity() const;
	//...
};

2、类UML图如下:

在这里,共通性是指:应用程序所提供的不同几何形状,必须以共通语法支持其操作(也就是说,相关函数必须同名)。具象类别(concrete classes)之间彼此独立定义。
请添加图片描述

3、静态多态实现或发生

当 templates被具象类别「实例化」,便获得(被赋予)多型的威力。

//绘制
template <typename GeoObj>
void myDraw(GeoObj const& obj)	//GeoObj是模板参数(template parameter)
{
	obj.draw();
}

// 处理两个 GeoObjs重心之间的距离
template <typename GeoObj1, typename GeoObj2>
Coord distance(GeoObj1 const& x1, GeoObj2 const& x2)
{
	Coord c = x1.center_of_gravity() - x2.center_of_gravity(); return c.abs();	// 传回坐标绝对值
}

四、动态多型vs静态多型

1、动态多型和静态多型分别支持不同的C++ 编程手法(idioms):

动态(绑定、执行期)多态性与模板的静态(非绑定、编译期)多态性。

2、优点和缺点

1)C++ 的动态多型表现出如下优点:
a、可优雅处理异质群集(Heterogeneous collections)。
b、可执行码的体积(executable code size)可能比较小。因为只需一个多型函数。静态多型则必 须产生不同的 template 实体以处理不同的类型。
b、程序代码可被完全编译,因而无需非得发布实作源码不可。如果你发行的是 template 库, 通常还需释出其实作源码。
2)相较之下,以下的优点属于C++ 静态多型:
a、内建型资料群集(collections of built in types)可被轻松实作出来。更一般地说,共通性接口 无需透过一个共通基础类别(common base class)来表达。
b、生成的程序代码可能执行速度较快。因为无需透过 pointers 进行间接操作,而且非虚拟函数(nonvirtual functions)被 inlined(内联化)的可能性比较大。
c、即使只提供部份接口的具象类型(concrete types)仍然可用(如果最终只有这一部份接口被应用程序用上的话)。

通常静态多型被认为比动态多型更具类型安全性(type safe),因为所有系结(binding)都被检查于编译期。举个例子,这种程序不可能存在这样的危险:将一个类型不匹配的物件插入一个从 template 具现出来的容器内。然而如果容器期望获得的元素是 pointer to common baseclass, 这个 pointer 有可能无意中指向不同类型的对象身上。

有错误或不足欢迎评论指出!创作不易,转载请注明出处。如有帮助,记得点赞关注哦(⊙o⊙)
更多内容请关注个人博客:https://blog.csdn.net/qq_43148810

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大胡子的艾娃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值