【課程支撐】[我的?C++程序設計課程教學材料](http://blog.csdn.net/sxhelijian/article/details/7056008)
要完成的任務詳見[第12周-任務2-雙肩挑干部](http://blog.csdn.net/sxhelijian/article/details/7543916)。題目要求
分別定義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++程序設計課程教學材料](http://blog.csdn.net/sxhelijian/article/details/7056008)