Bug現形記(一) 乙個多重繼承程式的查錯

2021-06-06 08:35:36 字數 1911 閱讀 5290

【課程支撐】我的 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 #include using namespace std;  

class teacher

;class cadre

;class teacher_cadre:public teacher,public cadre

;void teacher::display()

{ cout程式的執行結果是:

注意到畫紅圈的地方。尋找程式執行的流程,應該執行的是第50行,是teacher::display()輸出物件t1資訊時顯示了這一行。很時顯,紅圈中的?應該是性別 f 。看第50行沒有問題,那究竟在哪兒見著鬼了?

我決定用我們的法寶,除錯工具這個照妖鏡試試。問題出現在顯示時,我在第88行t1.show();處加了斷點並執行程式,開啟自動視窗(視窗中出現的正是當前**行涉及的物件的當前值),真相馬上出現了。先看截圖:

可以看到,可疑之處要輸出的性別***出現了3次:①來自基類teacher;②來自基類cadre;③來自派生類teacher_cadre。根據第50行**可以判斷,執行時出現的異常由於teacher::***造成的,而①處取值恰好為 『?』(其ascii碼值為52)。症狀掌握了。那**何在呢?

顯然,問題不在88行的show()函式,也不是48行teacher::display()的毛病。問題出現在顯示之前,物件根本沒有獲得正確的***值。87行在定義物件時做了初始化,這個程式很短,疑點馬上集中在對t1的初始化上。按照建構函式的執行過程逆著推上去,罪犯顯形了:在63-70行teacher的建構函式teacher::teacher(...)中,唯獨缺少了對*** 資料成員的賦值!

罪狀昭然於天下,bug伏法吧!

單就執行結果看,程式沒有問題了。但高度的責任感讓我想到③處還有個問號。再一看,來自派生類teacher_cadre中的資料成員,除了wages的值正確,其他全……。推及teacher_cadre的建構函式(80-83行),確實,只給wages做了初始化。

如果簡單些處理,在teacher_cadre::teacher_cadre(...)中再加些賦值不就行了?事情沒有這麼簡單。看teacher_cadre的宣告(32-46行),其資料成員多達8個!teacher_cadre繼承了兩個類的資料成員,其中有同名的造成了二義性,這還不夠麻煩,又將那些資料成員照抄著來了乙份,這樣,在派生類的物件中,同名的資料成員將被儲存3份。如果這樣的話,繼承還有何用?這反映了對繼承的理解還沒有到位,或許僅是粗心了。

如何更改程式,讀者應該清楚了。

作為結尾,再次提醒同學們用好除錯工具。

【課程支撐】我的 c++程式設計課程教學材料

BUG現形記(二) 偷工減料的複製建構函式

課程支撐 我的 c 程式設計課程教學材料 摘要 設計陣列類,要實現陣列類中兩個陣列相加的運算,程式卻陷入死迴圈。逐層排查,過載的加法正確,過載的賦值運算也看不出問題。跟蹤到賦值運算的實現中發現,傳遞的引數中有異常,終於找出了嫌疑犯 編制的複製建構函式偷工減料。閱讀提示 現在開啟你熟悉的c 跟隨作者的...

記乙個glslang的bug

這個錯誤是在vulkan專案出現的,由vulkan的validation layer報出 validation error unassigned corevalidation shader inconsistentspirv object 0 handle 0x1c89eff0fd8,type vk...

記乙個VTK8 0下的BUG

開發環境 win10 x64,vs2015,vtk8.1,qt5.8.0 報錯資訊 報錯nullper qvtkwidget的話是直接崩潰。解決方法 vtkrenderwindow在new之後還存在問題。原來是預設沒找到opengl2.0。加上下面這兩句搞定!include vtk module i...