基于内部视角的C++面向对象教学实践

2010-10-27 08:15庄巧莉
中国校外教育 2010年8期
关键词:面向对象调用函数

◆沈 炜 庄巧莉

(浙江理工大学信息电子学院)

基于内部视角的C++面向对象教学实践

◆沈 炜 庄巧莉

(浙江理工大学信息电子学院)

一、概述

面向对象程序设计是计算机专业学生的重要基础课,绝大多数高等院校都以 C++作为面向对象程序设计这门课程的教学语言。应该看到,面向对象技术的实现是有着严密的技术体系结构的,教学的过程,也是这一体系结构向学生逐步展示,让学生逐步理解并掌握的过程。但在具体的教学过程中,却有着很多的概念和方法,十分难以理解和掌握。其中,有些内容,甚至连教科书都出现自相矛盾的情况。如何采用更为有效的教学方法,避免出现类似的情况,实现良好的教学效果,是一个需要重点关注的问题。另一方面,计算机语言类课程,作为计算机专业课程最基础的课程,在教学中,由于开课一般先于其他专业课程,很难将其他专业课程的内容与当前课程内容相结合,容易陷入为教语言而教语言的境地。因此,采用何种方式,既能让学生容易理解语言中的难点,又能突破语言教学本身的限制,这是计算机语言类课程教学所面临的一个重大问题。

在教学准备过程中,我们对 C++语言的难点进行了深入地分析,发现这些内容往往都有这样的特点,即单纯从 C++语言本身,很难甚至无法诠释其技术原理,因此不引入新的知识,就无法让学生了解这些技术的实现原理,做到不仅“知其然”,而且“知其所以然”。因此,在教学过程中,我们提出采用基于内部视角的教学方法,在相关知识的教学过程中,引入了计算机内部实现的技术细节,在并不增加学生知识量的同时,通过说明技术的实现过程,使学生了解相关的技术原理,从而在掌握相关概念和方法的同时,加深对面向对象技术的了解和认识,突破语言教学本身所受的限制,为其他的相关专业课的学习打下较好的基础。

二、基于内部视角的教学方法论

所谓基于内部视角的教学方法,是在计算机程序设计语言的教学过程中,适当地引入包括汇编、编译、链接、调试和运行等相关技术实现的内容,从而使学生能够对一个程序从编辑到编译,乃至运行等各个环节中,计算机内部组织结构和运行过程的方法,有一个正确的认识。

显然,该方法对培养一名专业的程序员是十分有益的,这方面的内容,也是一名专业程序员所必须具备的。但该教学方法在使用上还有着很大的不确定性,主要包括:

(1)程序设计语言本身的限制。由于不同的程序设计语言在计算机体系中所处的层次不同,因此,这一方法的实施有着本质的不同。例如,象VB.Net、C#等语言,由于建立在.Net框架基础之上,技术实现细节复杂,因此较难采用此方法;而对于汇编语言来说,内存组织等相关技术内容,则是实践教学中的重要内容。对于象 C和 C++这样的中间语言来说,如何把握,则要根据教学内容进行取舍;

(2)引入程度的把握。计算机内部实现的技术细节有着先天的难度,实施中必须考虑学生的知识水平和结构,把握引入的程度。

我们认为,基于内部视角的教学方法在以 C++为编程语言的面向对象程序设计教学中,应该在如下方面引入:

(1)单纯以 C++语言无法完美解释的相关概念、技术等;

(2)作为学生选学的提高内容;

(3)实践教学环节的组成和补充。

在引入的内容方面,应遵循以下原则:引入的内容对学生目前的认知水平和知识结构来说,不会存在困难。

我们以若干实例来说明基于内部视角的教学方法的应用。

实例 1:继承类与基类构造函数的调用顺序

在这一内容方面,教材[1]认为,派生类对象的构造函数调用顺序是:基类构造函数先调用,派生类函数后调用。并用如下程序的输出来佐证。

//功能:演示继承关系中基类与派生类的构造函数与析构函数的调用次序。

类似的程序也出现在文献[2]和[3]中,而文献[2]和文献[3]也持同样的观点。但我们认为,这与构造函数的调用原理是矛盾的,至少是不严谨的。问题在于:一个类的对象成员在初始化时,要调用该类的构造函数,而派生类对象作为该派生类的对象,在初始化时,怎么会先调用非该派生类的构造函数呢?而且,这与继承类的构造函数的定义也相违背,因为基类构造函数的参数是由继承类的构造函数传递而来的,若是基类的构造函数先被调用,则所使用的参数从何而来?但单纯地如此说明,没有实验的佐证,不能给学生以深刻的印象。

在教学中,我们演示了应用Visual Studio 6的代码跟踪过程,来让学生充分地了解这一点。在跟踪过程中,打开汇编代码的显示开关,在0x40109D处,清晰地看到继承类的构造函数被调用了,如图 1所示,而在继承类构造函数调用过程中,基类的构造函数被调用。

图 1 构造函数调用顺序 (图中黑行分别表示调用派生类和基类构造函数)

这样,学生在观察的基础上能够得到关于基类、派生类构造函数正确的调用顺序。进一步跟踪还能够发现,虽然派生类对象构造函数调用顺序是先派生类再基类,但数据成员的初始化却是按先基类再派生类的顺序进行。因此,这一知识点可以用两句话概括:派生类对象构造函数调用顺序是先派生类后基类,而数据成员初始化则是先基类成员后派生类成员。在明确了整个过程之后,学生可以认识到,单纯依据 cout的输出来判断构造函数的调用顺序是不可靠的。

采用同样的方法,学生同样能够理解,C++程序中,代码可以先于main函数执行这一知识点。在这部分内容的教学中,学生直观地感受到语言代码在计算机内部的执行过程,同时,对程序的调试又有了新的认识和方法。

实例2:虚函数的调用

虚函数是一块较为难以理解的内容,很多学生说到虚函数就说心里“发虚”,原因是用 C++语言本身的知识,很难解释为什么指向基类对象的指针在指向派生类对象时,调用虚函数会进行动态绑定,而用对象直接调用虚函数却不存在这一情况,这一现象与前面指向对象的指针的知识有着很大的不同。仅按书本的内容,势必只能让学生了解这一现象,而不能让学生真正了解多态性这一能体现OOP思想的典型现象中包含的实现方法,这对建立和培养基于 OOP对现实世界的实体进行抽象的思想是不利的。

在这一节,我们在教学过程中,引入了虚函数表的知识,讲明如果一个类有虚函数,那么会在类中产生一个虚函数表,基类和派生类的同名虚函数在这个表中的位置是相同的,在调用虚函数时,程序是先查找这个虚函数表,然后根据表中的地址调用对应的虚函数。当指针指向基类对象或指向派生类对象时,所使用的虚函数表是不同的,这样,指针与虚函数表结合,从而实现了动态绑定这一运行时的多态性。在讲授中,我们只引入了虚函数表,但对虚函数表在内存中的位置,组织等则略过,这样既让学生掌握了原理,又不会因为繁琐的细节而失去对整体知识的把握,从而影响教学效果。

三、教学效果调查

在课后,我们对3个班的面向对象课程作了问卷调查,问卷的设计围绕着基于内部视角的教学方法展开。问卷发放 103份,总计收到有效问卷95份。在这些有效问卷中,有70.59%的学生认为,面向对象这门课在认识上存在着困难;有 39.2%的学生认为,困难的原因是内容本身的难度,有51%的学生认为,内容的难度是由“可以知其然,而难以知其所以然”造成的。从这个结果来看,引入适当的内容,使得有难度的知识点得到合理的诠释显然是必要的,显然,基于内部视角的教学方法正切合了这一实际。调查情况也证实了这一点,有 88.02%的学生认为,引入内部实现机制内容对本门课程有很大的帮助,同时,还有 82.44%的学生认为,这样的知识结构对今后的职业生涯也有很大的帮助。

从上述调查结果可以看出,基于内部视角的教学方法较为符合目前学生在面向对象程序设计这门课中的认知情况,符合学生在专业课中“想知其然并知其所以然”的认识能动性,并在较大程度上帮助学生更好地理解课程的内容,同时,也开拓了学生的视野,能够达到较为良好的教学效果。

四、结论

本文提出了一种在面向对象程序设计教学中的基于内部视角的教学方法,该方法主旨是在面向对象课程教学中,适当引入计算机内部实现的内容,从而能够使学生了解面向对象语言本身所难以诠释的内容,不仅让学生能够掌握相关课程内容,还能够了解相关技术实现机制,扩展了语言教学视野,从教学调查和实践来看,起到了比较好的教学效果。

应该看到,由于C++语言是基于中级语言C发展起来的,应用内部视角教学方法具有一定的优势,对于 java、C#等高级面向对象语言,如何恰当地应用该方法,则需要在今后的教学过程中加以探索。

[1]李师贤.面向对象程序设计基础.高等教育出版社,2005.

[2]Stephen Prata.C++Primer Plus Fifth Edition.Macmillan Computer Pub,2005.

[3]Bruce Eckel.Thinking in C++ Second Edition.机械工业出版社,2002.

浙江理工大学重点课程建设项目(ZDKC0908)。

猜你喜欢
面向对象调用函数
二次函数
第3讲 “函数”复习精讲
二次函数
函数备考精讲
核电项目物项调用管理的应用研究
面向对象方法在水蓄冷PLC编程中应用分析
系统虚拟化环境下客户机系统调用信息捕获与分析①
峰丛洼地农作物面向对象信息提取规则集
基于面向对象的车辆管理软件的研制与开发
面向对象的SoS体系结构建模方法及应用