【正文】
an People construct: Li Si People construct: Wang Wu Teacher construct: Wang Wu in Wuhan University Teacher destroy: Wang Wu in Wuhan University People destroy: Wang Wu People destroy: Li Si 多重繼承 (1/2) ? 單重繼承 ——一個(gè)派生類最多只能有一個(gè)基類 ? 多重繼承 ——一個(gè)派生類可以有多個(gè)基類 ? 派生類同時(shí)繼承多個(gè)基類的成員,更好的軟件重用 ? 可能會(huì)有大量的二義性,多個(gè)基類中可能包含同名變量或函數(shù) 多重繼承 (2/2) ? 多重繼承中解決訪問歧義的方法 基類名 + :: + 數(shù)據(jù)成員名(或成員函數(shù)) ? 明確指明要訪問定義于哪個(gè)基類中的成員 軟件漸增式開發(fā) ? 復(fù)合與繼承 ? 代碼重用的兩種方式 ? 都可以使新類重用已有類的數(shù)據(jù)和函數(shù) ? 有助于逐步開發(fā)功能越來越強(qiáng)大的程序 ? 使用復(fù)合還是繼承? ? 依據(jù)是實(shí)體之間的關(guān)系和程序設(shè)計(jì)的需要 例子 7:軟件漸增式開發(fā) (part 1,1/5) //文件 : interface for the Point class. if !defined __POINT__H__ define __POINT__H__ include class Point { friend ostreamamp。 Teacher t(Wang Wu, Wuhan University)。 } 例子 6:繼承關(guān)系中構(gòu)造函數(shù)和析構(gòu)函數(shù)的執(zhí)行順序 (5/5) //文件 //測試?yán)^承中基類和派生類的構(gòu)造函數(shù)與析構(gòu)函數(shù)的執(zhí)行順序 include include main () { { People tmp(Zhang San)。 } Teacher::~Teacher() { coutTeacher destroy: name in schoolendl。 strcpy(school,sch)。 }。 //構(gòu)造函數(shù) ~Teacher()。 delete []name。 coutPeople construct: nameendl。 endif 例子 6:繼承關(guān)系中構(gòu)造函數(shù)和析構(gòu)函數(shù)的執(zhí)行順序 (2/5) //文件 , 類 People的實(shí)現(xiàn) include include include //構(gòu)造函數(shù)的實(shí)現(xiàn) People::People(char *str) { name = new char[strlen(str)+1]。 //析構(gòu)函數(shù) protected: char *name。 } 程序運(yùn)行結(jié)果: People p: Zhang San, male Teacher t: Li Si, female in Wuhan University for 4 years. People p: Zhang San, male in ? for 4278034 years. People p: Li Si, female in Wuhan University for 4 years. 類指針 (3/3) ? 常用的程序設(shè)計(jì)方法 ? 用數(shù)組或鏈表組織和管理繼承關(guān)系中的各對(duì)象 ? 然后用基類指針操作它們 ? 麻煩 ——可能需要類型轉(zhuǎn)換 ? 下一章的多態(tài)性可以解決這個(gè)問題 繼承中的構(gòu)造函數(shù)和析構(gòu)函數(shù)(1/2) ? 派生類不繼承基類的構(gòu)造函數(shù)和析構(gòu)函數(shù) ? 派生類和基類的構(gòu)造函數(shù)和析構(gòu)函數(shù)之間是一種自動(dòng)調(diào)用的關(guān)系 ? 派生類的構(gòu)造函數(shù)需要調(diào)用基類的構(gòu)造函數(shù)對(duì)其中定義于基類的數(shù)據(jù)成員進(jìn)行初始化 ? 顯式調(diào)用(需要傳遞參數(shù)) ? 隱式調(diào)用(不需要傳遞參數(shù)) ? 派生類的析構(gòu)函數(shù)也需要調(diào)用基類的析構(gòu)函數(shù)做一些和基類相關(guān)的清理工作 繼承中的構(gòu)造函數(shù)和析構(gòu)函數(shù)(2/2) ? 構(gòu)造函數(shù)的執(zhí)行順序 ? 先調(diào)用基類的構(gòu)造函數(shù)初始化從基類繼承的數(shù)據(jù)成員 ? 再執(zhí)行自己的函數(shù)體初始化定義于派生類的數(shù)據(jù)成員 ? 析構(gòu)函數(shù)的執(zhí)行順序 ? 派生類的析構(gòu)函數(shù)先執(zhí)行自己的函數(shù)體 ? 再調(diào)用基類的析構(gòu)函數(shù) 例子 6:繼承關(guān)系中構(gòu)造函數(shù)和析構(gòu)函數(shù)的執(zhí)行順序 (1/5) //文件 //定義類 People if !defined __PEOPLE__H__ define __PEOPLE__H__ class People { public: People(char *str)。 cout \tin tptrgetSchool() for tptrgetWorkYears() years.endl。t。 //危險(xiǎn) , 訪問了不存在的屬性 cout\tin tptrgetSchool() for tptrgetWorkYears() years. endl。p。 例子 5:用類指針操作基類和派生類對(duì)象(8/9) //要調(diào)用定義于派生類中的函數(shù)必須進(jìn)行類型的強(qiáng)制轉(zhuǎn)換 cout\tin ((Teacher*)pptr)getSchool() for ((Teacher*)pptr)getWorkYears() years. endl endl。t。 //用基類指針指向基類對(duì)象 cout People p: pptrgetName() , (pptrgetSex() ? male : female) endl endl。 //用基類指針操作對(duì)象 pptr = amp。 } 例子 5:用類指針操作基類和派生類對(duì)象(7/9) //文件 include include main() { People p(Zhang San, 1), *pptr。 strcpy(str,school)。 } 例子 5:用類指針操作基類和派生類對(duì)象(6/9) int Teacher::getWorkYears() { return years。 years = (y0