Bug现形记(一):一个多重继承程序的查错
【课程支撑】我的 C++程序设计课程教学材料
要完成的任务详见第12周-任务2-双肩挑干部。题目要求
分别定义Teacher(教师)类和Cadre(干部)类,采用多重继承方式由这两个类派生出新类Teacher_Cadre(教师兼干部)。要求:
(1)在两个基类中都包含姓名、年龄、性别、地址、电话等数据成员。
(2)在Teacher类中还包含数据成员title(职称),在Cadre类中还包含数据成员post(职务),在Teacher_Cadre类中还包含数据成员wages(工资)。
(3)对两个基类中的姓名、年龄、性别、地址、电话等数据成员用相同的名字,在引用这些数据成员时,指定作用域。
(4)在类体中声明成员函数,在类外定义成员函数。
(5)在派生类Teacher_Cadre的成员函数show中调用Teacher类中的display函数,输出姓名、年龄、性别、职称、地址、电话,然后再用cout语句输出职务与工资。
下面是某同学的解答:
#include iostream #include string using namespace std; class Teacher public: Teacher(string nam, int a, char s, string addr, string tel,string t); void display(); protected: string name; int age; string title; string address; char sex; string telep; class Cadre public: Cadre(string nam, int a, char s, string addr, string t,string p); void display1(); protected: string name; int age; string address; char sex; string telep; string post; class Teacher_Cadre:public Teacher,public Cadre public: Teacher_Cadre(string nam, int a, char s, string addr, string tel,float w,string t,string p); void show(); protected: string name; int age; string title; string address; char sex; string telep; string post; float wages; void Teacher::display() cout Teacher::name " " Teacher::age " " Teacher::sex " " Teacher::address " " Teacher::telep " " title endl; void Cadre::display1() cout post endl; void Teacher_Cadre::show() display(); cout wages endl; Teacher::Teacher(string nam, int a, char s, string addr, string tel,string t) name=nam; age=a; address=addr; telep=tel; title=t; Cadre::Cadre(string nam, int a, char s, string addr, string tel,string p) name=nam; sex=s; age=a; address=addr; telep=tel; post=p; Teacher_Cadre::Teacher_Cadre(string nam, int a, char s, string addr, string tel,float w,string t,string p):Teacher(nam,a,s,addr,tel,t),Cadre(nam,a,s,addr,tel,p) wages=w; void main() Teacher_Cadre t1("malin",19,f,"yantai","18253593419",10000,"student","study"); t1.show(); t1.display1(); system("Pause");
程序的运行结果是:
注意到画红圈的地方。寻找程序执行的流程,应该执行的是第50行,是Teacher::display()输出对象t1信息时显示了这一行。很时显,红圈中的?应该是性别 f 。看第50行没有问题,那究竟在哪儿见着鬼了?
我决定用我们的法宝,调试工具这个照妖镜试试。问题出现在显示时,我在第88行t1.show();处加了断点并运行程序,打开自动窗口(窗口中出现的正是当前代码行涉及的对象的当前值),真相马上出现了。先看截屏:
可以看到,可疑之处要输出的性别sex出现了3次:①来自基类Teacher;②来自基类Cadre;③来自派生类Teacher_Cadre。根据第50行代码可以判断,运行时出现的异常由于Teacher::sex造成的,而①处取值恰好为 ‘?’(其ASCII码值为52)。症状掌握了。那病因何在呢?
显然,问题不在88行的show()函数,也不是48行Teacher::display()的毛病。问题出现在显示之前,对象根本没有获得正确的sex值。87行在定义对象时做了初始化,这个程序很短,疑点马上集中在对t1的初始化上。按照构造函数的执行过程逆着推上去,罪犯显形了:在63-70行Teacher的构造函数Teacher::Teacher(...)中,唯独缺少了对sex 数据成员的赋值!
罪状昭然于天下,Bug伏法吧!
单就运行结果看,程序没有问题了。但高度的责任感让我想到③处还有个问号。再一看,来自派生类Teacher_Cadre中的数据成员,除了wages的值正确,其他全……。推及Teacher_Cadre的构造函数(80-83行),确实,只给wages做了初始化。
如果简单些处理,在Teacher_Cadre::Teacher_Cadre(...)中再加些赋值不就行了?事情没有这么简单。看Teacher_Cadre的声明(32-46行),其数据成员多达8个!Teacher_Cadre继承了两个类的数据成员,其中有同名的造成了二义性,这还不够麻烦,又将那些数据成员照抄着来了一份,这样,在派生类的对象中,同名的数据成员将被存储3份。如果这样的话,继承还有何用?这反映了对继承的理解还没有到位,或许仅是粗心了。
如何更改程序,读者应该清楚了。
作为结尾,再次提醒同学们用好调试工具。
【课程支撑】我的 C++程序设计课程教学材料
Win32汇编:仿写多态与虚函数 多态性是面向对象的重要组成部分,利用多态可以设计和实现易于扩展的程序,所谓多态就是一个类函数有多重形态,具有不同功能的函数可以用同一个函数名,实现使用一个函数名调用不同内容的函数,从而返回不同的结果,这就是多态性,多态离不开虚函数的支撑,以下案例本人将深度分析虚函数实现机制,并通过汇编实现虚函数机制。
为什么程序员千万不要重写代码? 为什么程序员千万不要重写代码? 你所做的事情,也许暂时看不到成果,但不要灰心或焦虑,你不是没有成长,而是在扎根。 图片来自网络 程序员都有一颗工程师的心,所以当他们到一片新的场地想做的第一件事就是,将旧的一切推倒重来。
贺利坚 烟台大学计算机学院教师,建设系列学习资源,改革教学方法,为IT菜鸟建跑道,让大一的孩子会编程,为迷茫的大学生出主意,一起追求快乐的大学。 著书《逆袭大学:传给IT学子的正能量》,帮助处于迷茫中的大学
相关文章
- 同步TreeView中父结点和子结点的状态[以及Treeview的bug]
- 如何准确、高效地记录一个bug?测试新手速看~
- 1 bootstrap table null默认显示为 - 要查源码 2 记一个很无语的bug
- 背锅侠?程序出现bug是测试/开发工程师水平有限导致的?我只是个搬砖的......
- 某块 BUG 特别多,应该如何分析?
- 项目上线前出Bug,测试人该如何调整心态
- python bug解决方法:not all arguments converted during string formatting
- 与Qt的联系方式:邮件,论坛,销售,Bug报告
- 【Unity3D日常BUG】Unity3D中出现“动画片段必须标记为Legacy的警告”消除方法
- Fundebug微信小程序BUG监控服务支持Source Map
- Fundebug录屏插件更新至0.4.0,修复BUG,优化性能
- 复盘价值1000万的腾讯云硬盘固件"BUG"
- UOS20编译Qt程序:搭环境、解决bug
- 坦白说bug
- 一行代码解决AndFix热修复和热跟更新问题,集成了阿里的开源库,修复程序的缺陷bug漏洞和功能页面等
- Nest恒温器软件bug导致用户地址数据泄露 官方称只有邮编信息