C++静态关联与动态关联,怎样实现多态性

时间:2014-11-10 21:41    点击:

这一节将探讨C++是怎样实现多态性的。

从例12.2中修改后的程序可以看到, 同一个display函数在不同对象中有不同的作用,呈现了多态。计算机系统应该能正确地选择调用对象。

在现实生活中,多态性的例子是很多的。我们分析一下人是怎样处理多 态性的。例如,新生被录取人大学,在人学报到时,先有一名工作人员审查材料,他的职责是甄别资格,然后根据录取通知书上注明的录取的系和专业,将材料转到有关的系和专业,办理具体的注册人学手续,也可以看作调用不同部门的处理程序办理入学手续。在学 生眼里,这名工作人员是总的人口,所有新生办入学手续都要经过他。学生拿的是统一的录取通知书,但实际上分属不同的系,要进行不同的注册手续,这就是多态。那么,这名工 作人员怎么处理多态呢?凭什么把它分发到哪个系呢?就是根据录取通知书上的一个信 息(你被录取入本校某某专业)。可见,要区分就必须要有相关的信息,否则是无法判别的。

同样,编译系统要根据已有的信息,对同名函数的调用作出判断。例如函数的重载, 系统是根据参数的个数和类型的不同去找与之匹配的函数的。对于调用同一类族中的虚函数,应当在调用时用一定的方式告诉编译系统,你要调用的是哪个类对象中的函数。例如可以直接提供对象名,如studl.display()或grad1.display()。这样编译系统在对程序进行编译时,即能确定调用的是哪个类对象中的函数。

确定调用的具体对象的过程称为关联(binding)。binding原意是捆绑或连接,即把两样东西捆绑(或连接)在一起。在这里是指把一个函数名与一个类对象捆绑在一起,建立关联。一般地说,关联指把一个标识符和一个存储地址联系起来。在计算机字典中可以査到,所谓关联,是指计算机程序中不同的部分互相连接的过程。有些书中把binding译为联编、编联、束定、或兼顾音和意,称之为绑定。作者认为:从意思上说,关联比较确切, 也好理解。但是有些教程中用了联编这个术语。 大家在看到这个名词时,应当知道指的就是本节介绍的关联。

顺便说一句题外话,计算机领域中大部分术语是从外文翻译过来的,有许多译名是译得比较好的,能见名知意的。但也有一些则令人费解,甚至不大确切。例如在某些介绍计算机语言的书籍中,把project译为“工程”,使人难以理解,其实译为“项目”比较确切。 有些介绍计算机应用的书中充斥大量的术语,初听起来好像很唬人、很难懂,许多学习 C++的人往往被大量的专门术语吓住了,又难以理解其真正含义,不少人“见难而退”。 这个问题成为许多人学习C++的拦路虎。因此,应当提倡用通俗易懂的方法去阐明复杂的概念。其实,有许多看起来深奥难懂的概念和术语,捅破窗户纸后是很简单的。建议读者在初学时千万不要纠缠于名词术语的字面解释上,而要掌握其精神实质和应用方法。

说明:与其他编程语言相比,例如Java、C#等,C++的语法是最丰富最灵活的,同样也是最难掌握的,大家要循序渐进,莫求速成,在编程实践中不断翻阅和记忆。

前面所提到的函数重载和通过对象名调用的虚函数,在编译时即可确定其调用的虚函数属于哪一个类,其过程称为静态关联(static binding),由于是在运行前进行关联的, 故又称为早期关联(early binding)。函数重载属静态关联。

从例12.2我们中看到了怎样使用虚函数,在调用虚函数时并没有指定对象名,那么系统是怎样确定关联的呢?读者可以看到,是通过基类指针与虚函数的结合来实现多态性的。先定义了一个指向基类的指针变量,并使它指向相应的类对象,然后通过这个基类指针去调用虚函数(例如“pt->display()”)。显然,对这样的调用方式,编译系统在编译该行时是无法确定调用哪一个类对象的虚函数的。因为编译只作静态的语法检査,光从语句形式(例如“pt->display();”)是无法确定调用对象的。

在这样的情况下,编译系统把它放到运行阶段处理,在运行阶段确定关联关系。在运行阶段,基类指针变量先指向了某一个类对象,然后通过此指针变量调用该对象中的函数。此时调用哪一个对象的函数无疑是确定的。例如,先使pt指向grad1,再执行“pt->display()”,当然是调用grad1中的display函数。由于是在运行阶段把虚函数和类对象“绑定”在一起的,因此,此过程称为动态关联(dynamic binding)。这种多态性是动态的多态性,即运行阶段的多态性。

在运行阶段,指针可以先后指向不同的类对象,从而调用同一类族中不同类的虚函数。由于动态关联是在编译以后的运行阶段进行的,因此也称为滞后关联(late binding) 。

来源:未知//所属分类:基础教程/更新时间:2014-11-10 21:41
顶一下
(0)
0%
踩一下
(0)
0%
上一篇:C++虚函数、虚函数的作用和使用方法
下一篇:C++在什么情况下应当声明虚函数
相关内容