Thinking in C++: 第1章 多态性

本文内容摘抄自C++经典书籍:《Thinking in C++》

1.1.3 多态性

当处理类型层次结构时,程序员常常希望不把对象看作是某一特殊类型的成员,而把它看作基本类型成员,这样就可以编写不依赖于特殊类型的代码。在形体例子中,函数可以对一般形体进行操作,而不关心它们是圆、正方形还是三角形。所有的形体都能被绘制、擦除和移动,所以这些函数能简单地发送消息给一个形体对象,而不考虑这个对象如何处理这个消息。


这样,新添类型不影响原来的代码,这是扩展面向对象程序以处理新情况的最普通的方法。例如,可以派生出形体的一个新的子类,称为五边形,而不必修改那些处理一般形体的函数。通过派生新子类,很容易扩展程序,这个能力很重要,因为它极大地减少了软件维护的花费。(所谓“软件危机”正是由软件的实际花费远远超出人们的想象而产生的。)


如果试图把派生类型的对象看作它们的基本类型(圆看作形体,自行车看作车辆,鸬鹚看作鸟),就有一个问题:如果一个函数告诉一个一般形体去绘制它自己,或者告诉一个一般的车辆去行驶,或者告诉一只一般的鸟去飞,则编译器在编译时就不能确切地知道应当执行哪段代码。同样的问题是,消息发送时,程序员并不想知道将执行哪段代码。绘图函数能等同地应用于圆、正方形或三角形,对象根据它的特殊类型来执行合适的代码。如果增加一个新的子类,不用修改函数调用,就可以执行不同的代码。编译器不能确切地知道执行哪段代码,那么它应该怎么办呢?


在面向对象的程序设计中,答案是巧妙的。编译器并不做传统意义上的函数调用。由非O O P编译器产生的函数调用会引起与被调用代码的“早捆绑”,对于这一术语,读者可能还没有听说过,因为从来没有想到过它。早捆绑意味着编译器对特定的函数名产生调用,而连接器确定调用执行代码的绝对地址。对于 O O P,在程序运行之前,编译器不确定执行代码的地址,所以,当消息发送给一般对象时,需要采用其他的方案。


为了解决这一问题,面向对象语言采用“晚捆绑”的思想。当给对象发送消息时,在程序运行之前不去确定被调用的代码。编译器保证这个被调用的函数存在,并完成参数和返回值的类型检查,但是它不知道将执行的准确代码。


为了实现晚捆绑,编译器在真正调用的地方插入一段特殊的二进制代码。通过使用存放在对象自身中的信息,这段代码在运行时计算被调用函数的地址这样,每个对象就能根据一个指针的内容有不同的行为。当一个对象接收到消息时,它根据这个消息判断应当做什么。


程序员可以用关键字 v i r t u a l表明他希望某个函数有晚捆绑的灵活性,而并不需要懂得v i r t u a l的使用机制。没有它,就不能用 C + +做面向对象的程序设计。 Vi r t u a l函数(虚函数)表示允许在相同家族中的类有不同的行为。这些不同是引起多态行为的原因。


早起绑定:也称为静态绑定,即在编译器程序就确定了要执行的代码块。

晚期绑定:也称为动态绑定,即在程序运行期间决定要执行的代码块。


参考文章:

C++的虚函数和虚析构函数: http://blog.csdn.net/rl529014/article/details/51697483

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值