《面向对象程序设计》教学计划(13年8月)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
010011010111001110111001011011110001000111101010010100111000111101011101110001000110001000100011110111011101001101010100010000101011100001101010001000100111101010100001000111
01111000100001000101000111110
1010100010111000100010010100111011101110000101111000001110
001010000100111101001010100111100001100110011001101010100011100011001010101010111000011
1011101110111000100010001000111101000010011110100101010011
11000011001100110011010101000111000110010101010101110000111010100001001111010010101001111000011001100110011010101000 面向对象程序设计 08305121 教学计划
2013.8
目录
一、教学模式 (1)
二、研讨课的教学形式 (1)
三、研讨题 (3)
1C语言的特点 (3)
2定义结构体 (3)
3辩论赛 (3)
4定义复数类或有理数类中的成员函数(1) (3)
5定义复数类或有理数类中的成员函数(2) (3)
6自定义字符串类设计与实现之一(设置最大长度) (3)
7自定义字符串类设计与实现之二(无最大长度限制) (4)
8自定义字符串类设计与实现之三(运算符重载) (4)
9关于封装的专题讨论 (4)
10关于class与struct的异同 (4)
11多层继承 (4)
12除去冗余数据 (4)
13C++语言的特点 (5)
四、可选研讨题 (5)
1引用的作用 (5)
2几种排序算法的比较 (5)
3动态二维数组及其应用 (6)
4单向链表的基本处理函数 (6)
5浅谈“隐藏” (6)
6浅谈对象的空间 (6)
7自动单向链表及其应用 (6)
8单向链表类模板的设计与应用 (6)
9自定义字符串类的设计与实现之四 (6)
10自定义字符串类的设计与实现之五 (7)
11探究浮点型数据的存储格式 (7)
五、上机作业 (7)
1单向链表综合练习 (7)
2编写动态数组类TArray (7)
3关于类的封装,类的静态成员的应用。
(8)
4运算符重载,构造函数,模板动态数组(有一定难度) (9)
5继承与虚拟继承 (11)
6虚函数与多态性 (12)
六、教学进度一览 (14)
一、教学模式
本课程5学分,具体地分为3(大班集中讲授Lecture)+1(小班拓展研讨Seminar)+1(实验Practice)。
本课程的先修课程为《程序设计(C语言)》或《C++程序设计》。
课程选用《C++程序设计实用教程》(北京:清华大学出版社,2008.12)教材。
该教材分为三篇:计算与算法基础(第1章)、面向过程程序设计(第2-8章)、面向对象程序设计(第9-16章)。
本课程将用2周左右时间复习面向过程程序设计部分,并介绍C++面向过程程序设计部分对C语言的扩充内容;后8周介绍面向对象程序设计。
大班集中讲授时,将精讲、略讲教材中的主要内容,其余部分均需同学们自学。
小班拓展研讨时,将以同学们为主报告课外学习成果、提出问题并尝试解答、开展讨论。
教师的主要作用是控制研讨流程,记录研讨情况,并给积极参与研讨者加分。
根据需要,教师也可组织微型现场测验、上习题课等。
按4名同学一组分成小组开展课外学习和研讨活动,推选一名组长。
组内成员相互帮助,相互督促,共同提高。
以组长为中心,策划解题的方案,分配组员各自任务;每一个成员都有责任和义务,向组内的其他成员讲解自己的解题方法,直到大家全都理解;组内的每一个成员都必须努力学习,有责任不拖整体的后腿,以免影响其他成员的成绩。
根据课程进度安排,同学们需按时完成相应的准备工作积极参加研讨。
进行报告的小组应准备好报告所需的材料(如:PPT,源程序,测试运行结果,存在的问题或改进方面),报告时间不超过10分钟(建议PPT不超过10页)。
根据教师要求将报告所有材料电子版发送到任课教师指定的邮箱。
课程实验在校计算中心机房进行(时数=1学分×20学时/学分=20学时,即每周2学时),实验内容主要有验证所学内容、调试课后练习及课外探究设计题。
本课程的部分资料可在cppshu@ 邮箱(,用户名cppshu,口令123_abc)的邮件附件中下载。
该邮箱作为单向发布资料用,请不要回复给该邮箱。
二、研讨课的教学形式
1.席卡
每个学生自己做一个“席卡”:用一张A4纸打印
(参见文件席卡模板.xls)。
并按线折叠成三角柱,
每次上课前将自己的名牌置于课桌上显眼处。
或者上
讲台时也随之拿上讲台。
2.讨论课
a)分组。
每四位学生自由组合成小组,并选出一位小组长。
小组长负责组织课外研究、任务
分配等。
b)记分。
上台讲解、台下参加讨论都将被记分,将作为平时成绩的一部分。
平均每个学生都
有10分钟的上台讲解机会(请学生们自己不要放弃)。
定义“讨论课的基本形式和记分规则”:
指导思想:鼓励学生积极主动上台发言。
鼓励学生课前做充分的准备。
记分标准(上台时,每个学生拿上自己的席卡):
1)每次上台讲解内容不重复的学生记2分,且所在小组加记1分;
2)被指定上台讲解的学生如果不讲,扣1分,所在小组扣除1分;
3)讲解时有PPT或其它电子稿且格式清楚美观的学生再加记1分;
4)小组以外的学生补充讲解、积极参加讨论,学生记2分,所在小组加记1分;
5)小组的分数将作为等级系数追加到所在小组成员的平时成绩中。
定义“抛砖引玉方式”:
通过“摸彩”方式确定一个小组,由小组组长指定小组成员的讲解次序。
讨论形式:每次出一名成员交替上台讲一个不同点,每人只能讲一个,内容尽可能不重复,上台讲解的学生尽可能轮流。
然后按“讨论课的基本形式和记分规则”进行。
定义“小组竞赛方式”:
通过“摸彩”方式确定两个小组(依次记为A、B)展开竞赛。
讨论形式:A与B两小组,每次出一名成员交替上台讲一个不同点,每人只能讲一个,内容尽可能不重复,上台讲解的学生尽可能轮流。
然后按“讨论课的基本形式和记分规则”进行。
赢方小组的成员将每人追加1分。
定义“大组竞赛方式”:
通过“摸彩”方式确定四个小组,分成A与B两大组展开竞赛。
讨论形式:A与B两大组,每次出一名成员交替上台讲一个不同点,每人只能讲一个,内容尽可能不重复,上台讲解的学生尽可能轮流。
然后按“讨论课的基本形式和记分规则”进行。
赢方大组的成员将每人追加1分。
三、研讨题
1C语言的特点
包括语法,语义,作用,应用,编程思想,书写格式,历史,发展,与其他高级语言的比较等。
举例说明或解释。
【提示】可以在网上查找,等其他参考书中收集。
【讨论方式】按“大组竞赛方式”进行。
2定义结构体
定义结构体(struct),分别能作为如下数据结构的结点类型:①不带头结点的单向链表;②不带头结点的双向链表;③带头结点的单向链表;④带头结点的双向链表;⑤顺序表;⑥矩阵结构;
⑦二叉树结构;⑧学生课程表结构;⑨学生成绩单结构;⑩一卡通结构;⑪循环赛记分结构,⑫淘汰赛记分结构,等等。
【要求】选取其中2~3个进行讨论,写出各成员定义(包括:数据类型、成员名称、注释)。
【提示】可以在网上查找:首先理解如上各个表的定义,以及它们的应用范围和特点。
【讨论方式】按“抛砖引玉方式”进行。
3辩论赛
正方:编C++程序应该尽量用指针。
反方:编C++程序应该尽量不用指针。
【提示】正方可多举不同的实例,说明指针的益处和优点;反方:应多举不同的实例,说明指针的损处和缺点;
【讨论方式】按“小组竞赛方式”进行。
4定义复数类或有理数类中的成员函数(1)
【要求】写出这些成员的声明(包括函数返回类型、函数名、参数列表,考虑是否需要定义成常量成员函数);描述该函数的功能(不需要定义函数的具体实现);举一例对该函数的调用(使用)方式。
【讨论方式】按“抛砖引玉方式”进行。
5定义复数类或有理数类中的成员函数(2)
【要求】写出这些成员的声明(包括函数返回类型、函数名、参数列表,构造函数,析构函数);描述该函数的功能(不需要定义函数的具体实现);举一例对该函数的调用(使用)方式。
【讨论方式】按“抛砖引玉方式”进行。
6自定义字符串类设计与实现之一(设置最大长度)
【要求】封装C-字符串,设置最大处理长度MAX_LEN,实现字符串处理的基本功能;进行基本测试。
【讨论方式】按“抛砖引玉方式”进行。
7自定义字符串类设计与实现之二(无最大长度限制)
【要求】封装C-字符串,无最大处理长度限制,实现字符串处理的基本功能;进行基本测试。
【讨论方式】按“抛砖引玉方式”进行。
8自定义字符串类设计与实现之三(运算符重载)
【要求】以自定义字符串设计与实现之二为基础,增加字符串赋值(=)、字符串拼接(+)、字符串比较(<、<=、>、>=、==、!=)、方括号([]);进行基本测试。
【讨论方式】按“抛砖引玉方式”进行。
9关于封装的专题讨论
【提示】学生自由发挥,不作任何限制,该题目放在该课程内容刚开始前后即进行。
【讨论方式】按“抛砖引玉方式”进行。
10关于class与struct的异同
【提示】可以从网上搜索,并举实例说明。
【讨论方式】按“抛砖引玉方式”进行。
11多层继承
定义一个具有多层(至少3层)继承关系的实例。
用C++描述,并说明每一层的基本功能和作用。
【要求】写出每一层类名称,解释其主要作用;声明该类中的主要的成员函数(包括函数名、参数、返回),并解释,不需要写出具体的函数定义。
【讨论方式】按“抛砖引玉方式”进行。
12除去冗余数据
原有两个独立的银行存款类,以及源程序代码,但他们存在很多冗余,造成后期维护的困难和问题。
现要求,修改类定义,以去除(或至少减少)冗余性。
【要求】修改类定义,以及所有相应的源程序,并作出解释。
【提示】下图中有两个银行存款类,分别为Savings储蓄类和Checking结算类。
该银行存款类是示意性的,实际在银行中的存款业务要远多于示例的内容。
大方框代表类,类名在方框的顶部,小方框里面的名字是作为接口的公共成员函数,不在小方框里的名字是保护的数据成员。
●所有的储蓄构成一个链表,所有的结算也构成独立的一个链表。
链表中的结点个数即
账户数count,链表首指针为pFirst,结点中指向下一个结点的指针为pNext。
银
行存款一般有账号acntNumber和结算余额balance。
对于结算类,还要有异地汇
款的方式remittance,或信汇,或电汇,或其他转账结算方式。
●对银行存款类的操作有Deposit存款,Withdrawal取款,AccountNo取银行账号,
AcntBalance取账户中的余额。
●为了维护银行存款类中的链表,需要有操作:First取链表首指针,Next取下一个
结点,NoAccounts 取链表中的账户数。
与储蓄存款不同,对于结算存款,取款若为信汇(即邮寄汇款)或电汇(即电报汇款),
则要加收一定的手续费。
为此,设立数据成员remittance 汇款方式和成员函数
SetRemit 设置汇款方式,并且取款操作Withdrawal 也与储蓄存款不同。
【讨论方式】按“抛砖引玉方式”进行。
13 C++语言的特点
C++语言的特点(包括语法,语义,作用,应用,编程思想,书写格式,历史,发展,与C 语言有何不同,与其他高级语言的比较等)。
举例说明或解释。
【提示】可以在网上查找:从语法结构,编程思想,编程方式,开发应用,未来发展,等各方面。
【讨论方式】按“大组竞赛方式”进行。
四、可选研讨题
1 引用的作用
通过具体实例讨论引用的作用。
引用与指针各自的特点,并随课程的深入积累引用的更多、必不可少的作用。
2 几种排序算法的比较
排序是计算机科学与技术的基本问题。
针对目前已经接触到的多种排序算法(包括冒泡排序法、选择排序法、快速排序及直接调用系统提供的qsort 函数),讨论其算法设计思想、算法实现技术、算法性能分析与测试。
3动态二维数组及其应用
标准C/C++应用程序中,在定义数组(包括一维、二维等)时,各维的元素个数必须为常量。
本题要求利用堆内存空间实现动态二维数组,即元素个数在程序运算时确定。
用面向过程程序设计风格,即通过定义一系列函数实现动态二维数组创建、访问元素、释放等操作。
设计测试程序测试之。
希望通过该题的完成,进一步深入理解二维数组与一维数组的关系,特别是所谓的“行向量”首地址的概念等,并为后续设计与实现矩阵类打好基础。
4单向链表的基本处理函数
针对某种能构造单向链表的结点类型,设计并实现一系列函数实现单向链表(不带头结点)的基本操作:①根据给定数组创建链表;②增加结点;③删除结点;④释放所有结点;⑤模拟栈操作;⑥查找/继续查找;⑦其他(结点的顺序倒置、排序、归并、拆分等)。
再设计相应的测试函数进行综合、全面测试。
【提示】注意“引用”、“指针”的使用;分析带头结点的单向链表与不带头结点的单向链表的特点,特别是C++中有了“引用”概念后的优势。
5浅谈“隐藏”
比较C语言struct与C++的struct(或class)的异同点;各种访问属性对数据或方法的保护作用;隐藏this指针的意义。
通过实例说明编译型语言源程序文件与目标代码文件(库文件)之间的关系,头文件与目标代码文件之间的关系。
6浅谈对象的空间
通过实例说明对象的空间构成、封装隐藏、创建(申请)与销毁(回收),C++类的构造函数、复制构造函数、析构函数、赋值运算符的重要意义。
7自动单向链表及其应用
①验证各种变量(全局变量、静态全局变量、静态局部变量、自动变量、函数形参、函数返回值、数组元素、动态变量、动态数组元素,对象数据成员,对象的静态数据成员(第11章))的生命周期;
②讨论递归函数形式参数、局部自动变量、静态局部变量等的生命周期。
8单向链表类模板的设计与应用
研究LinkList.h文件,利用该文件所提供的单向链表类模板完成一个“XX管理系统”的应用程序(如:学生成绩管理程序、图书管理系统、通讯录等)。
比较自动单向链表与一般的单向链表的特点。
9自定义字符串类的设计与实现之四
不使用C-字符串,即不使用串结束标志字符'\0'重新设计“自定义字符串类”,尽量与系统提供的string类相似。
设计测试程序测试之。
10自定义字符串类的设计与实现之五
尽管字符串与向量有些不同(如:元素的数据类型可以相同或不同,它们的输入/输出、运算等基本操作有所不同),但考虑到字符串、向量的元素在内存中连续存放(属于顺序表)等共同特点。
故可以将其共性抽象出来,设计一个抽象类模板,然后由其派生向量类、字符串类。
再利用虚函数或纯虚函数实现动态多态性(参见练习14(3))。
11探究浮点型数据的存储格式
学习IEEE 754标准,通过程序分析float、double型数据(如:0.0,0.0/0.0,1.0/0.0,sqrt(2.0),exp(1.0),2*atan(1.0,0.0)等)在内存中的具体存放形式,即8*sizeof(float)位或8*sizeof(double)位的具体值。
【提示】请上网搜索IEEE 754标准。
可采用如下方法之一读取每个字节:①将数据存入二进制文件(数据在文件中的存放形式与其在内存中的格式一致),然后再按二进制文件打开,但按字节读取(每个浮点型数据共占sizeof(数据类型)字节);②使用联合体union(参见其他参考书或在互联网上搜索相关知识),以浮点型数据格式写入,用等长度的字节量读取;③根据浮点型数据变量的地址强制转换赋值给字符型指针变量。
获得sizeof(数据类型)个字节的具体地址后,便可按字节取出其8个位的具体内容(可能需要用到一些位操作运算符,如:右移>>、位与&、位或|等)。
请注意C/C++语言在存放具体数据时低位在前高位在后。
五、上机作业
1单向链表综合练习
【要求】用单向链表实现“XX管理系统”,管理的内容不限,具有基本的功能:①添加结点;
②删除结点;③输出数据;④释放所有结点;⑤修改结点的值;⑥统计计算;⑦其他必要的功能。
2编写动态数组类TArray
【说明】预设如下主函数
int main()
{
TArray a(10); // a是一个double 类型的长度为10动态数组
TArray b; // b是一个double 类型的尚未确定其长度的动态数组
b.SetLen(7); // 使b成为一个长度为7的动态数组
double d[10] = { 1,2,3,4,5,6,7,8,9,10 };
a.Input(d,10); // 把c中的10个元素复制到a中
a.Print(); // 打印a中的元素
TArray c(a); // 创建了一个与a一样的c数组
b = a; // 把a的内容复制给b
a.SetElem(0,6); // 把第0个元素的值重新赋值为6
b.Exchange(4,2); // 交换b中第4个和第2个元素的内容
b.Print(); // 打印b中的元素
a.Print(); // 打印a中的元素
c.Print(); // 打印c中的元素
return 0;
}
3 关于类的封装,类的静态成员的应用。
(1)设计一个学生类,包含学生学号、姓名、课程、成绩等基本信息,计算学生的平均成绩。
【要求】定义学生类Student,有三门课(课程名称及其他必要的数据成员名称自定)。
静态存放每门课的总分。
有如下主函数的测试源程序。
int main()
{
Student stu1("200906264","Li Weiwei",88,75,91); //定义一个学生及成绩stu1.display(); //打印该学生的信息
Student stu2("200902164","Chen Hanfu",86,78,93); //再定义一个学生及成绩stu2.display(); //打印该学生的信息
Student stu3("200908079","Zhan Gaolin",94,69,97);//再定义一个学生及成绩stu2.display(); //打印该学生的信息
cout << "The average grade of course1: " << stu1.average1() << endl;
cout << "The average grade of course2: " << stu2.average2() << endl;
cout << "The average grade of course3: " << stu3.average3() << endl;
return 0;
}
(2)有一信息管理系统,要求检查每一个登录系统的用户(User)的用户名和口令,系统检查合格以后方可登录系统,编写C++程序。
【要求】定义用户类User。
口令加密(自定义。
例如:把输入的密码串中每一个字符转换成对应的ASCII码,再加上该字符输入码中的位置编号,所得到一个数值再取256的模,得到新的字串。
如:输入"ab4U+",密码序列为,97+1,98+2,52+3,85+4,43+5),即字符串"cd7Y0"。
定义一个对应的解码程序。
有如下的主函数测试程序。
int main()
{
char name[20], pass[20];
User u1("LiWei", "liwei99"); // 注册一个用户(用户名和密码)u1.Adduser("ChenHanfu", "20090208"); // 再注册一个用户(用户名和密码)User::Adduser("ZhanGaolin", 199146"); // 再注册一个用户(用户名和密码)cout << "Input username:";
cin >> name;
cout << "Input password:";
cin >> pass;
if(User::login(name,pass)>=0) // 判别输入的用户是否成功登录cout << "Success login!" << endl;
else
cout << "login fail!" << endl;
return 0;
}
4 运算符重载,构造函数,模板动态数组(有一定难度)
设计有理数类Rational(有理数能表示成两个整数的商)。
【提示】建议该类中有两个数据成员,分别存放分子、分母。
设计一个内部的计算最大公因数函数、约分函数,必要的构造函数。
【要求】①保证分母为正整数,当分子与分母有公因子时,能自动约分。
如果分子能除尽分母,则分母是1,这正好代表整数情况。
②重载的运算符:算术及算数迭代赋值运算+、-、*、/、+=、-=、*=、/=(还应包括与整型数据的运算)。
③前(后)增(减)量运算。
④double类型转换符。
⑤插入/抽取运算符(<<、>>)。
⑤修改上机作业2中的Tarray类,将其修改成类模板。
有如下的主函数参考测试程序,请增加新的测试能力,测试所有设计的函数。
int main()
{
Rational a(1,3); // a是一个三分之一的有理式
Rational b(4,6); // b是一个六分之四的有理式
Rational c; // c是一个0有理式
c = a + b; // c中得到a与b相加的结果
cout << "c = a + b = " << a << "+" << b << "=" << c << endl;
c += a;
cout << "c = c + a = " << c << endl;
c.Print(); // 输出:1又3分之1
cout << endl;
double d;
d = c;
cout << " d = " << d << endl; // 输出结果:1.33333
Rational e(1); // e是一个1的有理式
c = e + 2; //
c.Println("c = "); // Println是一个调用Print函数后再换行的函数
Rational f(-2,5,10); // f是一个负的2有10分之5的有理式,即-2.5
f.Println("f=");
Rational g(2,-5,10); // g也是一个负的2有10分之5的有理式,即-2.5
g.Println("g = ");
Rational h(2,5,-10); // h也是一个负的2有10分之5的有理式,即-2.5
h.Println("h = ");
f = e++; // e中的值变成2, f中存放1
f.Println("f = ");
e.Println("e = ");
f = ++e; // e中的值变成3, f中存放3
f.Println("f = ");
TArray<Rational> x(3); // x是一个具有3个Rational对象的动态数组,默认值0 x[0] = a;
x[1] = b;
x[2] = c;
x.Println("x = "); // 打印x中的所有元素
return 0;
}
5 继承与虚拟继承
【要求】有两题,合并检查。
【作业检查方法】可以把如下两题的main函数分别改成main1和main2函数,增加如下main 函数。
int main()
{
main1();
main2();
return 0;
}
(1) 继承。
编写一个Point类,派生出Rectangle类和Circle类,计算各派生类对象的面积Area()。
有如下main函数不能变动。
int main()
{
Rectangle R(1,2,3,4);
cout << "R.Area() = " << R.Area() << endl;
Circle C(5,6,7);
cout << "C.Area() = " << C.Area() << endl;
return 0;
}
运行结果:
Teacher,学生类和教师类又共同派生出在职读书的教师类Stu_Teach。
人员类有姓名、性别、身份证号、出生年月等信息;学生类有学号、成绩等信息;教师类有职称等信息。
有如下main函数不能变动。
int main()
{
Stu_Teach ST("Liu_xiaopeng", 'M', "428120************",
"1976-05-27", "Professor", "Computer Science");
ST.display();
return 0;
}
运行结果:
6 虚函数与多态性
(1) 主要目的是练习“继承”、“虚继承”和“虚函数”等多态性的编程方法。
请编程定一个Vector类;定义ColVector类和RowVector类,它们都是Vector的派生类。
有如下main()函数和fun不能变动,也不要重载该fun函数。
void fun(const Vector& vec) // Vector是一种向量类,是其它向量的基类。
{
Vector * vx = vec.NewThis(); // 创建复制一个派生对象
vx->Display(); // 打印对象的内容
vx->DeleteThis(); // 释放一个对象
}
int main()
{
ColVector cv(1,2,3,4); // ColVector是一种列向量类,是Vector的派生cv.Display(); // cv打印自己的元素
RowVector rv(5,6,7,8); // RowVector是一种行向量类,是Vector的派生rv.Display(); // rv打印自己的元素
Vector * cvx = cv.NewThis(); // cv从堆中复制了一个自己的副本cvx->Display(); // cvx打印自己的元素
Vector* rvx = rv.NewThis(); // rv从堆中复制了一个自己的副本rvx->Display(); // rvx打印自己的元素
cvx->DeleteThis(); // cvx 把自己从堆中释放了
rvx->DeleteThis(); // rvx 把自己从堆中释放了
fun(cv);
fun(rv);
return 0;
}
运行结果:
六、教学进度一览。