版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、PART III面 向 對(duì) 象 的 程 序 設(shè) 計(jì)引引 言言概 要 回 顧基于過(guò)程的程序設(shè)計(jì)基于對(duì)象的程序設(shè)計(jì)面向?qū)ο蟮某绦蛟O(shè)計(jì) 類的生成、設(shè)計(jì)類對(duì)象的使用C+過(guò)程化語(yǔ)言基礎(chǔ)問(wèn) 題 的 回顧 俄羅斯方塊的設(shè)計(jì)與實(shí)現(xiàn) 基于過(guò)程的設(shè)計(jì)與實(shí)現(xiàn) 基于對(duì)象的設(shè)計(jì)與實(shí)現(xiàn) 方塊對(duì)象:七種方塊對(duì)象 圖框?qū)ο螅贺?fù)責(zé)繪制俄羅斯方塊運(yùn)行的圖框界面 判定對(duì)象:負(fù)責(zé)消行、統(tǒng)計(jì)分?jǐn)?shù)、方塊到頂游戲終結(jié)基 于 對(duì) 象 的 解 決 方 案 基 于 對(duì) 象 的 解 決 方 案 分 析 七種方塊: 公有屬性:顏色、速度、 不同屬性:形狀、 共同操作:右移、左移、下移、變形 各種操作由于形狀的不同而有不同的實(shí)現(xiàn) 這7種方塊的移動(dòng)和變
2、形的實(shí)現(xiàn)方法不同,顯示也不同,因此不能用同一個(gè)類來(lái)描述 設(shè)計(jì)7個(gè)類分別描述7種方塊 7個(gè)方塊類中又有很多相同的,如顏色等數(shù)據(jù)屬性,都要四種移動(dòng)操作,只是各自的實(shí)現(xiàn)方法有所不同問(wèn)題1:共同的數(shù)據(jù)屬性在7個(gè)類中各自描述一次,顯得繁瑣,重復(fù),能夠簡(jiǎn)化為統(tǒng)一描述?問(wèn)題2:相同的操作能否在統(tǒng)一描述的同時(shí)方便地根據(jù)方塊類型調(diào)用不同的實(shí)現(xiàn)? 繼承和多態(tài)結(jié) 論 僅僅支持基于類的設(shè)計(jì)、生成和類對(duì)象的使用是不能稱為面向?qū)ο蟮某绦蛟O(shè)計(jì) 面向?qū)ο蟪绦蛟O(shè)計(jì)的四大主要特點(diǎn) 抽象 封裝 繼承 多態(tài)基于對(duì)象的程序設(shè)計(jì)面向?qū)ο蟮某绦蛟O(shè)計(jì)PARTIII 綱 要010102020303繼承與派生(重點(diǎn))繼承與派生(重點(diǎn))多態(tài)性與虛
3、函數(shù)(重點(diǎn))多態(tài)性與虛函數(shù)(重點(diǎn))輸入輸出流(常用)輸入輸出流(常用)0404C+ C+ 工具工具繼繼 承承 與與 派派 生生問(wèn) 題 回 顧 與 分 析 共同的數(shù)據(jù)屬性在7個(gè)方塊類中各自描述一次,顯得繁瑣,重復(fù),能夠簡(jiǎn)化為統(tǒng)一描述? 分析 先統(tǒng)一描述所有方塊的共性以及對(duì)全體方塊的處理功能;描述某一種方塊時(shí),首先說(shuō)明它是其中之一,然后再逐一描述這種方塊的個(gè)性 面向?qū)ο蟮某绦蛟O(shè)計(jì)中類的繼承與派生繼 承 與 派 生類類 的的 繼繼 承承派生類可以獲得基類的已有派生類可以獲得基類的已有特性特性派生類繼承了基類的所有數(shù)派生類繼承了基類的所有數(shù)據(jù)成員和成員函數(shù)據(jù)成員和成員函數(shù)類的繼承是層次結(jié)構(gòu)的類的繼承是
4、層次結(jié)構(gòu)的基類是派生類的抽象基類是派生類的抽象類的派生類的派生基類產(chǎn)生了一個(gè)和具有基類基類產(chǎn)生了一個(gè)和具有基類各種特性的新的子類各種特性的新的子類派生類可以對(duì)成員作必要的派生類可以對(duì)成員作必要的增加和調(diào)整增加和調(diào)整派生類又可以作為基類再派派生類又可以作為基類再派生出新的派生類生出新的派生類派生類是基類的具體化派生類是基類的具體化繼承派生在一個(gè)已經(jīng)存在的類(基類在一個(gè)已經(jīng)存在的類(基類/ /父類)的基礎(chǔ)之上父類)的基礎(chǔ)之上建立一個(gè)新的類(派生類建立一個(gè)新的類(派生類/ /子類)子類)繼 承 與 派 生 的 基 本 形 式單 繼 承 和 多 重 繼 承 單繼承 一個(gè)派生類只能由一個(gè)基類派生而來(lái) 一
5、個(gè)子類只有一個(gè)父類 多重繼承 一個(gè)派生類由多個(gè)(=2)基類派生而成 一個(gè)子類有兩個(gè)或者兩個(gè)以上的父類派 生 類 的 聲 明 一般形式class : ;派 生 類 實(shí) 例基類(普通學(xué)生類)基類(普通學(xué)生類)class student private: int ID; char *name; float score11; public: student(int n1,char*nm1) student()delete name; void print() . void get_name() ;派生類聲明(大學(xué)生類)派生類聲明(大學(xué)生類)class undergstudent : public :
6、public studentstudent private: char *major; /新增加的數(shù)據(jù)成員 float score40; public: void get_data print_major( ) /新增加的成員函數(shù) void print () 基類(普通學(xué)生類)基類(普通學(xué)生類)派生類聲明(大學(xué)生類)派生類聲明(大學(xué)生類)大學(xué)生類(未考慮訪問(wèn)屬性)大學(xué)生類(未考慮訪問(wèn)屬性) int ID; int ID; char char * *name;name; float score40;float score40; char char * *major;major; print_ma
7、jor( ) print_major( ) void print() .void print() . . .派 生 類 的 構(gòu) 成 兩大部分兩大部分 從基類繼承來(lái)的成員從基類繼承來(lái)的成員 聲明派生類時(shí)增加的部分聲明派生類時(shí)增加的部分 每一部分都分別包括數(shù)據(jù)成員和成員函數(shù)每一部分都分別包括數(shù)據(jù)成員和成員函數(shù) 構(gòu)成方式構(gòu)成方式 并非基類的成員和派生類增加成員的簡(jiǎn)單加和并非基類的成員和派生類增加成員的簡(jiǎn)單加和 接收基類的全部成員接收基類的全部成員 調(diào)整從基類接收的成員調(diào)整從基類接收的成員 聲明派生類時(shí)增加的成員聲明派生類時(shí)增加的成員 根據(jù)需要增加成員根據(jù)需要增加成員 定義派生類的構(gòu)造函數(shù)和定義派生類
8、的構(gòu)造函數(shù)和析構(gòu)析構(gòu)函數(shù)函數(shù)(不能從基類繼承而來(lái))(不能從基類繼承而來(lái))基 類 成 員 的 接 收 和 調(diào) 整 無(wú)條件地全部接收無(wú)條件地全部接收 不接收析構(gòu)函數(shù)和構(gòu)造函數(shù)不接收析構(gòu)函數(shù)和構(gòu)造函數(shù) 接收到的基類成員可以調(diào)整接收到的基類成員可以調(diào)整 通過(guò)指定繼承方式改變成員的訪問(wèn)通過(guò)指定繼承方式改變成員的訪問(wèn)屬性屬性 可以聲明同名成員加以覆蓋可以聲明同名成員加以覆蓋派 生 類 的 繼 承 方 式 三種繼承方式 public private protected 不同的繼承方式?jīng)Q定了基類成員在派生類中訪問(wèn)屬性派 生 類 成 員 的 訪 問(wèn) 屬 性 分情況處理 基類的成員函數(shù)訪問(wèn)基類成員 派生類成員函數(shù)
9、訪問(wèn)派生類自己增加的成員 基類的成員函數(shù)訪問(wèn)派生類的成員 派生類外訪問(wèn)派生類的成員 根據(jù)成員的訪問(wèn)屬性判定能否由類外訪問(wèn)該成員 派生類的成員函數(shù)訪問(wèn)基類的成員 派生類外訪問(wèn)基類的成員 核心問(wèn)題:如何確定基類成員在派生類中的訪問(wèn)屬性 基類成員聲明的訪問(wèn)屬性 派生類對(duì)基類的繼承方式三 種 繼 承 方 式 下 派 生 類 中基 類 成 員 的 訪 問(wèn) 控 制 權(quán) 限 繼承繼承 方式方式基類基類成員成員公有繼承公有繼承私有繼承私有繼承保護(hù)繼承保護(hù)繼承公有成員公有成員公有公有私有私有保護(hù)保護(hù)私有成員私有成員派生類成員不派生類成員不可訪問(wèn)可訪問(wèn)派生類成員不派生類成員不可訪問(wèn)可訪問(wèn)派生類成員不派生類成員不可
10、訪問(wèn)可訪問(wèn)保護(hù)成員保護(hù)成員保護(hù)保護(hù)私有私有保護(hù)保護(hù)公 有 繼 承基類的私有成員并沒(méi)有成為派生類的私有成員基類的私有成員僅僅只有基類的成員函數(shù)才能應(yīng)用基類的私有成員是派生類的不可訪問(wèn)的成員基類的私有成員只能通過(guò)基類的公有成員函數(shù)加以訪問(wèn)實(shí)例:基類student派生類undergstudent(公有繼承)假設(shè)一創(chuàng)建一個(gè)對(duì)象freshman是一個(gè)大一新生(Bob,10009,CS, )如何能夠正確獲取name、ID、major等信息?方 案 一 主函數(shù)調(diào)用freshman的公有成員函數(shù)get_data 派生類中g(shù)et_data如下定義:coutname;coutID;coutmajor;原因:nam
11、e和ID是基類的私有成員,在派生類中不可訪問(wèn)方 案 二 基類中公有成員函數(shù)get_namecoutname; 基類中公有成員函數(shù)get_IDcoutID; 派生類中公有成員函數(shù)get_majorcoutmajor; 主函數(shù)中分別調(diào)用freshman的get_name、get_ID和get_major完成信息的獲取 公有繼承下,基類的公有成員在派生類中仍為公有,可在派生類外訪問(wèn)方 案 三 主函數(shù)調(diào)用freshman的公有成員函數(shù)get_data 派生類中g(shù)et_data如下定義:get_name; /調(diào)用基類的成員函數(shù)get_ID;/調(diào)用基類的成員函數(shù)coutmajor; 基類中公有成員函數(shù)ge
12、t_name定義如下:coutname; 基類中公有成員函數(shù)get_ID定義如下:cout set_major(“EE”);/*不能訪問(wèn)派生類增加的成員私 有 繼 承私有基類的公有成員和保護(hù)成員相當(dāng)于派生類中的私有成員派生類的成員可以訪問(wèn)私有基類的公有成員和保護(hù)成員,但是派生類外不能訪問(wèn)實(shí)例:情況與前述相同,唯一的區(qū)別是派生類undergstudent以私有繼承的方式由student類派生而成方 案 一 主函數(shù)調(diào)用freshman的公有成員函數(shù)get_data 派生類中g(shù)et_data如下定義:coutname;coutID;coutmajor;原因:name和ID是基類的私有成員,公有繼承下
13、在派生類中已不可訪問(wèn),私有繼承下依然不可行方 案 二 基類中公有成員函數(shù)get_namecoutname; 基類中公有成員函數(shù)get_IDcoutID; 派生類中公有成員函數(shù)get_majorcoutmajor; 主函數(shù)中分別調(diào)用freshman的get_name、get_ID和get_major完成信息的獲取 原因:私有繼承下,基類的公有成員等同于派生類的私有成員,無(wú)法在派生類外訪問(wèn)方 案 三 主函數(shù)調(diào)用freshman的公有成員函數(shù)get_data 派生類中g(shù)et_data如下定義:get_name; /調(diào)用基類的成員函數(shù)get_ID;/調(diào)用基類的成員函數(shù)coutmajor; 基類中公有成
14、員函數(shù)get_name定義如下:coutname; 基類中公有成員函數(shù)get_ID定義如下:coutID;保 護(hù) 繼 承 保護(hù)成員 受保護(hù)的成員不能為類外訪問(wèn),但是可以被派生類的成員函數(shù)所引用基類(普通學(xué)生類)class student private: int ID; char *name; float score11; public: ;派生類聲明(大學(xué)生類)class undergstudent : public : public studentstudent private: char *major; /新增加的數(shù)據(jù)成員 float score40; public: class stu
15、dent protected: int ID; char *name; float score11; public: ;保 護(hù) 繼 承保護(hù)基類的公有成員和保護(hù)成員相當(dāng)于派生類中的保護(hù)成員派生類的成員可以訪問(wèn)保護(hù)基類的公有成員和保護(hù)成員,但是派生類外不能訪問(wèn)實(shí)例:情況與前述相同,但是派生類undergstudent以保護(hù)繼承的方式由student類派生而成第 一 種 情 形(ID 和name為私有數(shù)據(jù)) 基類(普通學(xué)生類)class student private:private: int ID; char *name; float score11; public: student(int n1
16、,char*nm1) student()delete name; void print() . void get_name() ;派生類聲明(大學(xué)生類)class undergstudent : protected : protected studentstudent private: char *major; /新增加的數(shù)據(jù)成員 float score40; public: void get_data print_major( ) /新增加的成員函數(shù) void print () 方 案 一 主函數(shù)調(diào)用freshman的公有成員函數(shù)get_data 派生類中g(shù)et_data如下定義:coutn
17、ame;coutID;coutmajor;原因:name和ID是基類的私有成員,保護(hù)繼承下在派生類中依然不可訪問(wèn)方 案 二 基類中公有成員函數(shù)get_namecoutname; 基類中公有成員函數(shù)get_IDcoutID; 派生類中公有成員函數(shù)get_majorcoutmajor; 主函數(shù)中分別調(diào)用freshman的get_name、get_ID和get_major完成信息的獲取 原因:保護(hù)繼承下,基類的公有成員等同于派生類的保護(hù)成員,無(wú)法在派生類外訪問(wèn)方 案 三 主函數(shù)調(diào)用freshman的公有成員函數(shù)get_data 派生類中g(shù)et_data如下定義:get_name; /調(diào)用基類的成員函
18、數(shù)get_ID;/調(diào)用基類的成員函數(shù)coutmajor; 基類中公有成員函數(shù)get_name定義如下:coutname; 基類中公有成員函數(shù)get_ID定義如下:coutID;第二種情形 (ID和name為保護(hù)成員數(shù)據(jù)) 基類(普通學(xué)生類)class student protected:protected: int ID; char *name; private: float score11; public: student(int n1,char*nm1) student()delete name; void print() . void get_name() ;派生類聲明(大學(xué)生類)cla
19、ss undergstudent : protected : protected studentstudent private: char *major; /新增加的數(shù)據(jù)成員 float score40; public: void get_data print_major( ) /新增加的成員函數(shù) void print () 方 案 一 主函數(shù)調(diào)用freshman的公有成員函數(shù)get_data 派生類中g(shù)et_data如下定義:coutname;coutID;coutmajor;原因:name和ID是基類的保護(hù)成員,公有繼承下和保護(hù)繼承下派生類中可以訪問(wèn)方 案 二 基類中公有成員函數(shù)get_n
20、amecoutname; 基類中公有成員函數(shù)get_IDcoutID; 派生類中公有成員函數(shù)get_majorcoutmajor; 主函數(shù)中分別調(diào)用freshman的get_name、get_ID和get_major完成信息的獲取 原因:保護(hù)繼承下,基類的公有成員等同于派生類的保護(hù)成員,無(wú)法在派生類外訪問(wèn)方 案 三 主函數(shù)調(diào)用freshman的公有成員函數(shù)get_data 派生類中g(shù)et_data如下定義:get_name; /調(diào)用基類的成員函數(shù)get_ID;/調(diào)用基類的成員函數(shù)coutmajor; 基類中公有成員函數(shù)get_name定義如下:coutname; 基類中公有成員函數(shù)get_ID
21、定義如下:coutID;保 護(hù) 成 員 和 保 護(hù) 繼 承 的 效 用 在類的在類的層次繼承結(jié)構(gòu)層次繼承結(jié)構(gòu)中找到數(shù)據(jù)中找到數(shù)據(jù)共享與成員隱蔽之間的最佳均衡共享與成員隱蔽之間的最佳均衡 如果需要在派生類中引用基類的如果需要在派生類中引用基類的某些成員,應(yīng)當(dāng)將基類中的這些某些成員,應(yīng)當(dāng)將基類中的這些成員聲明為成員聲明為protectedprotected,而非,而非privateprivate 以student類中的ID和name為例 如果聲明成為private,將造成派生類無(wú)法訪問(wèn)的局面,使得派生類的使用很不方便 如果聲明成為public,使得基類的數(shù)據(jù)隱蔽性受到一定的損傷 如果聲明成為pro
22、tected,派生類可以訪問(wèn)從而使得基類和派生類之間可以實(shí)現(xiàn)數(shù)據(jù)共享,基類和派生類的外部都不能訪問(wèn),保障了數(shù)據(jù)的隱蔽性多 級(jí) 派 生 下 的 訪 問(wèn) 屬 性 類的層次繼承結(jié)構(gòu)導(dǎo)致了類的多級(jí)派生 基類 基類的派生類 派生類的派生類 直接派生類 vs. 間接派生類 直接基類 vs. 間接基類 多級(jí)派生情況下各成員的訪問(wèn)屬性 在基類和其直接派生類之間按照一級(jí)派生訪問(wèn)屬性的原則確定各成員的訪問(wèn)屬性后逐級(jí)向下遷移派 生 類 的 構(gòu) 造 函 數(shù) 回顧:構(gòu)造函數(shù)的作用 對(duì)類中的數(shù)據(jù)成員進(jìn)行初始化 派生類的構(gòu)造函數(shù)的特殊性 派生類的數(shù)據(jù)成員構(gòu)成較為特殊 從基類中接收來(lái)的數(shù)據(jù)成員 派生類自己增加的數(shù)據(jù)成員 派生
23、類并沒(méi)有繼承基類的構(gòu)造函數(shù) 派生類的構(gòu)造函數(shù)的初始化工作 基類數(shù)據(jù)成員的初始化工作 派生類增加的數(shù)據(jù)成員的初始化工作派 生 類 實(shí) 例基類(普通學(xué)生類)基類(普通學(xué)生類)class student private: int ID; char *name; float score11; public: student(int n1,char*nm1) student()delete name; void print() . void get_name() ;派生類聲明(大學(xué)生類)派生類聲明(大學(xué)生類)class undergstudent : public : public studentstu
24、dent private: char *major; /新增加的數(shù)據(jù)成員 float score40; public: void get_data print_major( ) /新增加的成員函數(shù) void print () 實(shí) 例:大學(xué)生類undergstudent的構(gòu)造函數(shù)方案一undergstudentundergstudent(int n, string stu_name, string (int n, string stu_name, string stu_major, float stu_major, float * * scoreList) scoreList) ID = n;
25、ID = n; name= stu_name; name= stu_name; major = stu_major; major = stu_major; score = scoreList; score = scoreList; 派生類無(wú)法訪問(wèn)基類的私有成員數(shù)派生類無(wú)法訪問(wèn)基類的私有成員數(shù)據(jù)據(jù)方案二undergstudentundergstudent(int n, string stu_name, string (int n, string stu_name, string stu_major, float stu_major, float * * scoreList) scoreList)
26、 student(n, stu_name); student(n, stu_name); / /調(diào)用基類構(gòu)造函數(shù)調(diào)用基類構(gòu)造函數(shù) major = stu_major; major = stu_major; score = scoreList; score = scoreList; 不能在派生類構(gòu)造函數(shù)體中顯式調(diào)不能在派生類構(gòu)造函數(shù)體中顯式調(diào)用構(gòu)造函數(shù)!雖然能通過(guò)編譯,但用構(gòu)造函數(shù)!雖然能通過(guò)編譯,但結(jié)果不對(duì)結(jié)果不對(duì)派 生 類 構(gòu) 造 函 數(shù) 的 解 決 之 道方案三undergstudentundergstudent(int n, string stu_name, string (int n,
27、 string stu_name, string stu_major, float stu_major, float * * scoreList) scoreList): student(n, stu_name);: student(n, stu_name);/調(diào)用基類構(gòu)造函數(shù)調(diào)用基類構(gòu)造函數(shù) / /* *派生類的函數(shù)體中只對(duì)派生類派生類的函數(shù)體中只對(duì)派生類新增的數(shù)據(jù)成員進(jìn)行初始化新增的數(shù)據(jù)成員進(jìn)行初始化* */ / major = stu_major; major = stu_major; score = scoreList; score = scoreList; 解決的辦法是通過(guò)成員初始化
28、表來(lái)完成基類數(shù)據(jù)成員的初始化,在成員初始化表中可以顯式調(diào)用基類構(gòu)造函數(shù)派生類的函數(shù)體完成新增數(shù)據(jù)成員的初始化派 生 類 構(gòu) 造 函 數(shù) 的 基 本 形 式() :();說(shuō)明:1、如果派生類構(gòu)造函數(shù)在類的外面定義,類體中只需要寫這個(gè)函數(shù)的聲明:() ;2、總參數(shù)表中的參數(shù)包括了基類構(gòu)造函數(shù)所需的參數(shù)和派生類新增數(shù)據(jù)成員初始化所需的參數(shù) 生成一個(gè)類對(duì)象(10009,bob,CS,) undergstudent(n, stu_name, stu_major, scorelist):student(n, stu_name)構(gòu)造函數(shù)的成員初始化表有 子 對(duì) 象 的 派 生 類 的 構(gòu) 造 函 數(shù) 子對(duì)象
29、 類的數(shù)據(jù)成員本身就是一個(gè)類對(duì)象class undergstudent : public : public studentstudent private: char *major; float score40; Teacher* tutor; /子對(duì)象 public: class teacher private: int ID; char* name; char* title; public: 分析: 對(duì)象建立時(shí)需要對(duì)它的數(shù)據(jù)成員進(jìn)行初始化 派生類構(gòu)造函數(shù)對(duì)其數(shù)據(jù)成員進(jìn)行初始化的時(shí)候也需要對(duì)其中的子對(duì)象進(jìn)行初始化 在成員初始化表中顯式調(diào)用子對(duì)象的構(gòu)造函數(shù)undergstudent (int n
30、, string stu_name, string stu_major, float * scoreList, int T_n, string T_name, string T_title): student(n, stu_name), tutor (T_n, T_name, T_title)派 生 類 構(gòu) 造 函 數(shù) 的 一 般 形 式():(), ();派生類構(gòu)造函數(shù)的任務(wù)派生類構(gòu)造函數(shù)的任務(wù)初始化基類數(shù)據(jù)成員初始化基類數(shù)據(jù)成員初始化子對(duì)象數(shù)據(jù)成員初始化子對(duì)象數(shù)據(jù)成員初始化其它派生類數(shù)據(jù)成員初始化其它派生類數(shù)據(jù)成員派生類構(gòu)造函數(shù)執(zhí)行順序派生類構(gòu)造函數(shù)執(zhí)行順序調(diào)用基類構(gòu)造函數(shù)調(diào)用基類構(gòu)造函數(shù)
31、調(diào)用子對(duì)象構(gòu)造函數(shù)調(diào)用子對(duì)象構(gòu)造函數(shù)執(zhí)行派生類構(gòu)造函數(shù)體執(zhí)行派生類構(gòu)造函數(shù)體特 殊 形 式 的 派 生 類 構(gòu) 造 函 數(shù) 多層派生時(shí),不需要在成員初始化表中理出其上每一層派生類的構(gòu)造函數(shù),只需要列出其直接基類的構(gòu)造函數(shù)即可 派生類新增成員無(wú)需任何初始化時(shí),派生類構(gòu)造函數(shù)的函數(shù)體唯恐 如果基類沒(méi)有定義構(gòu)造函數(shù),或者定義了沒(méi)有參數(shù)的構(gòu)造函數(shù),派生類定義構(gòu)造函數(shù)可以不寫基類構(gòu)造函數(shù),派生類構(gòu)造函數(shù)調(diào)用時(shí),系統(tǒng)會(huì)自動(dòng)首先調(diào)用基類的默認(rèn)構(gòu)造函數(shù)派 生 類 的 析 構(gòu) 函 數(shù) 回顧:析構(gòu)函數(shù)的作用 在對(duì)象撤銷之前,進(jìn)行必要的清理工作 派生類的析構(gòu)函數(shù) 對(duì)派生類新增加的成員進(jìn)行清理 根據(jù)需要定義相應(yīng)的析構(gòu)
32、函數(shù) 如果有子對(duì)象,還需要對(duì)子對(duì)象進(jìn)行清理 調(diào)用子對(duì)象的析構(gòu)函數(shù)完成 需要對(duì)接收自基類的成員進(jìn)行清理 調(diào)用基類的析構(gòu)函數(shù)完成派生類析構(gòu)函數(shù)的任務(wù)派生類析構(gòu)函數(shù)的任務(wù)清理基類數(shù)據(jù)成員清理基類數(shù)據(jù)成員清理子對(duì)象數(shù)據(jù)成員清理子對(duì)象數(shù)據(jù)成員清理其它派生類數(shù)據(jù)成員清理其它派生類數(shù)據(jù)成員派生類析構(gòu)函數(shù)執(zhí)行順序派生類析構(gòu)函數(shù)執(zhí)行順序調(diào)用基類析構(gòu)函數(shù)調(diào)用基類析構(gòu)函數(shù)調(diào)用子對(duì)象析構(gòu)函數(shù)調(diào)用子對(duì)象析構(gòu)函數(shù)執(zhí)行派生類析構(gòu)函數(shù)部分執(zhí)行派生類析構(gòu)函數(shù)部分派 生 類 的 同 名 覆 蓋 覆蓋規(guī)則 基類的同名成員在派生類中被屏蔽,成為不可見(jiàn)的 定義在派生類對(duì)象模塊中通過(guò)對(duì)象名訪問(wèn)同名的成員,訪問(wèn)的是派生類的成員 實(shí)例:st
33、udent student_A;undergstudent student_B;student_A.print();/調(diào)用基類中的成員函數(shù)printstudent_B.print();/調(diào)用派生類中的成員函數(shù)printstudent_B.student:print();/指明作用域而調(diào)用基類成員數(shù)據(jù)成員的覆蓋只要命名相同即可成員函數(shù)的覆蓋不僅函數(shù)名要相同,函數(shù)的參數(shù)表包括參數(shù)個(gè)數(shù)和類型都要相同多 重 繼 承 一個(gè)類可以從一個(gè)或者多個(gè)基類派生而來(lái)。根據(jù)派生類繼承基類的個(gè)數(shù),將繼承分為單繼承和多繼承。 當(dāng)派生類有多個(gè)基類時(shí)稱為多繼承。單繼承可以看作是多繼承的一個(gè)特例,多繼承可以看作是多個(gè)單繼承的組
34、合,它們有很多相同特性。 實(shí)例教師類在職研究生類研究生類多 重 繼 承 派 生 類 的 定 義class : , , ;多 重 繼 承 派 生 類 的 構(gòu) 造 函 數(shù) 成員初始化表中需要包含多個(gè)基類構(gòu)造函數(shù) 一般形式():(), , () ;多 重 繼 承 的 二 義 性 問(wèn) 題 情形一:兩個(gè)基類有同名成員class gstudent: protected: int ID; char* name; char* major; public: init(); class teacher protected: int ID; char* name; char* title; public: init
35、(); class onjobgstudent: public gstudent, public teacher public: void print(); cout IDendl; coutnameendl; main() onjobgstudent Teach_A; Teach_A.init(); /該調(diào)用哪個(gè)init()? Teach_A.print(); /print函數(shù)該輸出哪個(gè)ID? /研究生學(xué)號(hào)和教師工號(hào)并不同二義性解 決 方 案 一用作用域運(yùn)算符“:”進(jìn)行限定,顯式訪問(wèn)基類成員。main()main() onjobgstudent Teach_A; onjobgstudent
36、Teach_A; Teach_A.Teacher.init();Teach_A.Teacher.init(); Teach_A.gstudent.init(); Teach_A.gstudent.init(); Teach_A.print(); Teach_A.print(); class onjobgstudent: class onjobgstudent: public gstudent, public gstudent, public teacher public teacher public: public: void print(); void print(); cout coutT
37、eacher.IDTeacher.IDendl;endl; cout coutTT endl; endl; cout coutgstudent.IDgstudent.IDendl;endl; cout coutmajormajorendl;endl; 派生類的成員派生類的成員函數(shù)訪問(wèn)基類函數(shù)訪問(wèn)基類成員,不必寫成員,不必寫對(duì)象名對(duì)象名情 形 二:兩個(gè)基類和派生類都有同名成員class gstudent:class gstudent: protected: protected: int ID; int ID; char char* * name; na
38、me; char char* * major; major; public: public: void init(); void init(); class teacherclass teacher protected: protected: int ID; int ID; char char* * name; name; charchar* * title; title; public public: : void init(); void init(); class onjobgstudent: class onjobgstudent: public gstudent, public gs
39、tudent, public teacher public teacher public: public: void init(); void init(); void print(); void print(); main()main() onjobgstudent Teach_A; onjobgstudent Teach_A; Teach_A.init();Teach_A.init(); / /調(diào)用哪個(gè)調(diào)用哪個(gè)initinit? /根據(jù)同名覆蓋原則根據(jù)同名覆蓋原則 / /調(diào)用調(diào)用onjobgstudentonjobgstudent的的initinit Teach_A.print();Tea
40、ch_A.print(); 無(wú)二義性 內(nèi)在問(wèn)題分析 Teacher_A.init調(diào)用類onjobgstudent的init函數(shù)進(jìn)行初始化,而類onjobgstudent的init函數(shù)分別調(diào)用了gstudent的init函數(shù)和teacher的init函數(shù)進(jìn)行基類數(shù)據(jù)成員的初始化 Teacher_A這個(gè)對(duì)象中保留了多份同名成員 teacher.ID gstudent.ID teacher.ID 和gstudent.ID互不相同必須保留 和相同保留多份同名數(shù)據(jù)占用空間,易出錯(cuò)解 決 方 案 二:虛
41、基 類 的 引 入 派生類:在職研究生類 直接基類:教師類、研究生類 直接基類來(lái)自于同一個(gè)基類 (共同基類):Person類 教師類和研究生類 具有數(shù)據(jù)成員ID,不再具有name person類具有數(shù)據(jù)成員name情況是否有改善?教師類繼承person類的name研究生類繼承person類的name在職研究生類中仍有兩個(gè)同名name數(shù)據(jù)備份教師類在職研究生類研究生類Person類publicpublicpublicpublic虛 基 類 的 作 用 和 聲 明將Person類聲明為虛基類 使在職研究生類在多重繼承來(lái)自共同基類的直接基類時(shí)只保留一份同名成員 在職研究生類中只有一份name數(shù)據(jù),來(lái)
42、自于間接基類Person類虛基類的聲明教師類在職研究生類研究生類Person類virtual publicvirtual publicpublicpublicclass person /正常申明class teacher :virtual public persoclass gstudent :virtual public personclass onjobgstudent : public teacher, public gstudent注 意 事 項(xiàng) 虛基類在聲明派生類時(shí),通過(guò)制定繼承方式虛基類在聲明派生類時(shí),通過(guò)制定繼承方式時(shí)聲明時(shí)聲明class 派生類名派生類名 : virtual 繼
43、承方式繼承方式 虛基類名虛基類名 虛基類需要在其虛基類需要在其所有所有直接派生類中聲明為虛直接派生類中聲明為虛基類基類person類為虛基類,其直接派生類類為虛基類,其直接派生類teacher和和gstudent均需聲明均需聲明person為虛基類,缺一為虛基類,缺一不可不可課 后 思 考 題1 1、目前情況下,類、目前情況下,類teacherteacher和類和類gstudentgstudent仍然有同名數(shù)據(jù)成員:仍然有同名數(shù)據(jù)成員:IDID,請(qǐng)問(wèn)類請(qǐng)問(wèn)類onjobgstuentonjobgstuent如何處理該同如何處理該同名數(shù)據(jù)成員?名數(shù)據(jù)成員?2 2、如果、如果personperson
44、類中也增加一個(gè)數(shù)據(jù)類中也增加一個(gè)數(shù)據(jù)成員為成員為IDID用于存儲(chǔ)每個(gè)人的身份證號(hào),用于存儲(chǔ)每個(gè)人的身份證號(hào),又會(huì)出現(xiàn)什么情況?又會(huì)出現(xiàn)什么情況?虛 基 類 的 初 始 化引入虛基類之前的情況 在職研究生類的構(gòu)造函數(shù)進(jìn)行初始化時(shí),調(diào)用教師類和研究生類各自的構(gòu)造函數(shù)進(jìn)行初始化,而教師類和研究生類各自的構(gòu)造函數(shù)又分別去調(diào)用person類的構(gòu)造函數(shù) 在職研究生類的構(gòu)造函數(shù)中只需要寫出它的直接基類teacher和gstudent的構(gòu)造函數(shù)即可教師類在職研究生類研究生類Person類publicpublicpublicpublic引 入 虛 基 類 后,在職研究生類中只保留了一份同名數(shù)據(jù)name 同名數(shù)據(jù)
45、來(lái)自虛基類Person類這一份數(shù)據(jù)成員的初始化必須由派生類直接完成 如果沿用原來(lái)的方式,共同基類person的初始化由teacher和gstudent分別調(diào)用,而進(jìn)行了多次初始化 不合理教師類在職研究生類研究生類Person類virtual publicvirtual publicpublicpublic虛 基 類 初 始 化 的 規(guī) 定 最后的派生類不僅要負(fù)責(zé)對(duì)其直接基最后的派生類不僅要負(fù)責(zé)對(duì)其直接基類進(jìn)行初始化,還需要負(fù)責(zé)虛基類的類進(jìn)行初始化,還需要負(fù)責(zé)虛基類的初始化初始化onjobgstudent (int t_n, int s_n, string fullname, string T_
46、title, string S_major): person (fullname), gstudent (s_n, S_major, fullname), teacher(t_n,T_tile, fullname)虛 基 類 初 始 化 的 說(shuō) 明 C+編譯系統(tǒng)只執(zhí)行最后派生類對(duì)虛基類的構(gòu)造函數(shù)的調(diào)用,而忽略虛基類的其它派生類對(duì)虛基類的構(gòu)造函數(shù)的調(diào)用,保證虛基類的數(shù)據(jù)成員不會(huì)被多次初始化 構(gòu)造函數(shù)的調(diào)用順序(1)先調(diào)用虛基類的構(gòu)造函數(shù),再調(diào)用非虛基類的構(gòu)造函數(shù)(2)若同一層次中包含多個(gè)虛基類,其調(diào)用順序?yàn)槎x時(shí)的順序(3)若虛基類由非虛基類派生而來(lái),則仍按先調(diào)用基類構(gòu)造函數(shù),再調(diào)用派生類構(gòu)造函
47、數(shù)的順序引 入 繼 承 后 的 解 決 方 案 (俄 羅 斯 方 塊)class Shape int color;/基類成員 void leftshift() ; ;class L-shape: public shape /方塊類派生了L型方塊類 /L型方塊類繼承了方塊類,自動(dòng)擁有其成員 char L-box2; /定義L型方塊類的形狀屬性 void leftshift() ; ;不 足 之 處 基類的leftshift()等成員函數(shù)的函數(shù)體均為空,在實(shí)現(xiàn)部分仍要寫出函數(shù)體,顯得冗余,本無(wú)必要,但為了統(tǒng)一規(guī)范類簇的基本行為,又不得不如此 主控程序每次隨機(jī)生成7種方塊中的一種,然后響應(yīng)鍵盤控制完
48、成相應(yīng)的操作和顯示,由于7種方塊對(duì)象分屬于7種方塊派生類創(chuàng)建,盡管主控程序中方塊對(duì)象的行為和操作保持一致,仍然需要將相似的代碼重復(fù)7遍,以保證調(diào)用和方塊對(duì)象一致的派生類中的成員函數(shù)while (;) int i =random()%7; if i = 0 create a L-shape object; detect keyboard; operate L-shape object; display; rule-control; if i= 1 create a 1-shape object; detect keyboard; operate 1-shape object; display;
49、rule-control; . 程序不夠簡(jiǎn)潔To be continuedTo be continued多態(tài)性和虛函多態(tài)性和虛函數(shù)數(shù)多多 態(tài)態(tài) 性性 和和 虛虛 函函 數(shù)數(shù)問(wèn) 題 的 分 析 有一個(gè)類簇,一個(gè)基類派生了不同的派生類,這個(gè)類簇具有統(tǒng)一的基本行為function,但是不同的派生類實(shí)現(xiàn)function的方法不統(tǒng)一 不同的派生類創(chuàng)建了一組不同的對(duì)象,這一組對(duì)象,接收到相同的信息,都需要完成function行為,但是由于對(duì)象由不同的派生類所創(chuàng)建,不同派生類完成類似功能的方法不同,需要分別調(diào)用不同內(nèi)容的函數(shù)來(lái)完成 目前的解決機(jī)制 既然function是這個(gè)類簇的統(tǒng)一的基本行為,所以基類中定
50、義統(tǒng)一的成員函數(shù)funciton 不同的派生類定義各自同名的成員函數(shù)function,根據(jù)同名覆蓋原則屏蔽基類的成員函數(shù),不同派生類創(chuàng)建的對(duì)象調(diào)用各自對(duì)應(yīng)的成員函數(shù)實(shí) 例class student:class student: protected: protected: int ID; int ID; char char* * name; name; public: public: void init(); void init(); void print(); void print(); class bachelor : public studentclass bachelor : publi
51、c student protected: protected: char char* * major; major; float score40;float score40; public public: : void init(); void init(); void print(); void print(); class master: public student, class master: public student, protected: protected: char char* * major; major; teacher advisor;/ teacher adviso
52、r;/導(dǎo)師導(dǎo)師 float score20;float score20; public public: : void init(); void init(); void print(); void print(); class doctor: public student, class doctor: public student, protected: protected: char char* * major; major; teacher advisor5;/ teacher advisor5;/導(dǎo)師組導(dǎo)師組 float score10;float score10; public pub
53、lic: : void init(); void init(); void print(); void print(); 需要打印所有學(xué)生的學(xué)籍情況bachelor stu1;stu1.print();master stu2;stu2.print();doctor stu3stu3.print();主函數(shù)中建立了3個(gè)不同類的對(duì)象,進(jìn)行了類似的操作,重復(fù)寫了3遍類似的語(yǔ)句繁瑣,不夠簡(jiǎn)潔 理想狀態(tài)student *stu3=&stu1,&stu2,&stu3; /聲明基類指針數(shù)組for(int i=0;iprint(); /*單一指令,希望根據(jù)對(duì)象的類型調(diào)用對(duì)應(yīng)派生類的特定
54、函數(shù)*/ 對(duì)象stu1,stu2,stu3來(lái)自于同一個(gè)基類student,而基類與派生類對(duì)象間遵循類型兼容規(guī)則事實(shí)上,由于stu0, stu1和stu2只能訪問(wèn)基類成員,所以調(diào)用的都是student類中的print函數(shù)解 決 機(jī) 制 動(dòng)態(tài)多態(tài) 相對(duì)于靜態(tài)多態(tài)而言:函數(shù)重載、運(yùn)算符重載 特點(diǎn):程序編譯時(shí)知道調(diào)用哪個(gè)函數(shù)(編譯時(shí)的多態(tài)性) 編譯時(shí)不能確定調(diào)用那個(gè)函數(shù),只有在程序運(yùn)行是才能動(dòng)態(tài)確定操作所針對(duì)的對(duì)象 理想狀態(tài)下,stui.print()調(diào)用哪個(gè)函數(shù)取決于運(yùn)行時(shí)i的值 運(yùn)行時(shí)的多態(tài)性 引入虛函數(shù)虛 函 數(shù) 虛函數(shù)是一類特殊的基類成員函數(shù) 在基類中聲明,類內(nèi)用virtual 聲明 在派生類
55、中可重新定義,但函數(shù)名、函數(shù)類型、函數(shù)參數(shù)個(gè)數(shù)和類型必須與基類的虛函數(shù)相同,根據(jù)派生類需要重新定義函數(shù)體 派生類中沒(méi)有重新定義時(shí),派生類簡(jiǎn)單繼承其直接基類的虛函數(shù) 虛函數(shù)是C+語(yǔ)言的多態(tài)性質(zhì)和動(dòng)態(tài)綁定的關(guān)鍵虛 函 數(shù) 的 特 性 特點(diǎn) 一個(gè)成員函數(shù)被申明為虛函數(shù)后,同一類簇內(nèi)所有類內(nèi)不能再定義與該虛函數(shù)具有相同參數(shù)和函數(shù)返回值類型的同名非virtual函數(shù) 一個(gè)函數(shù)一旦被聲明為虛函數(shù),則無(wú)論聲明它的類被繼承了多少層,在每一層派生類中該函數(shù)都保持虛函數(shù)特性。因此,在派生類中重新定義該函數(shù)時(shí),可以省略關(guān)鍵字virtual。但是,為了提高程序的可讀性,往往不省略 當(dāng)有虛函數(shù)聲明時(shí),virtual關(guān)鍵
56、字只用在虛函數(shù)的聲明中,不能用在虛函數(shù)定義中虛 函 數(shù) 的 作 用 作用 可以通過(guò)基類指針或者引用來(lái)訪問(wèn)基類和派生類中的同名函數(shù) 基類指針指向某一派生類對(duì)象(符合賦值兼容原則),調(diào)用指針指向的派生類對(duì)象中的函數(shù)而非基類或者其它派生類中的函數(shù)(虛函數(shù)的作用) 突破了原來(lái)急了指針僅僅只能指向派生類對(duì)象中的基類部分的限制實(shí) 例class student:class student: protected: protected: int ID; int ID; char char* * name; name; public: public: void init(); void init(); virtu
57、al virtual void print();void print(); student student * *stu3=&stu1,&stu2,&stu3; stu3=&stu1,&stu2,&stu3; / /聲明基類指針數(shù)組聲明基類指針數(shù)組for(int i=0;i3;i+)for(int i=0;iprint(); stui-print(); / /* *printprint已申明為虛函數(shù)已申明為虛函數(shù)* */ / /stu0 /stu0將調(diào)用將調(diào)用bachelorbachelor的的printprint /stu1 /stu1將調(diào)用將
58、調(diào)用mastermaster的的printprint /stu0 /stu0將調(diào)用將調(diào)用doctordoctor的的printprint 多 態(tài) 的 分 類 C+中多態(tài)的分類 重載多態(tài):函數(shù)重載和運(yùn)算符重載 強(qiáng)制多態(tài):強(qiáng)制類型轉(zhuǎn)換 包含多態(tài):虛函數(shù) 參數(shù)多態(tài):函數(shù)模板和類模板 多 態(tài) 的 編 譯 實(shí) 現(xiàn) 編譯系統(tǒng)要根據(jù)已有的信息,對(duì)于同名函數(shù)的調(diào)用做出判斷,確定調(diào)用搞得是哪個(gè)函數(shù) 關(guān)聯(lián)/binding/聯(lián)編/綁定 靜態(tài)多態(tài) 靜態(tài)關(guān)聯(lián)、早期關(guān)聯(lián) 動(dòng)態(tài)多態(tài) 動(dòng)態(tài)關(guān)聯(lián)、滯后關(guān)聯(lián) C+規(guī)定,動(dòng)態(tài)關(guān)聯(lián)通過(guò)繼承和虛函數(shù)來(lái)實(shí)現(xiàn)虛 函 數(shù) 申 明 注 意 事 項(xiàng) 靜態(tài)成員函數(shù)不能聲明為虛函數(shù)。因?yàn)殪o態(tài)成員函數(shù)
59、不屬于某一個(gè)對(duì)象,沒(méi)有多態(tài)性的特征 構(gòu)造函數(shù)不能是虛函數(shù) 內(nèi)聯(lián)成員函數(shù)不能聲明為虛函數(shù)。因?yàn)閮?nèi)聯(lián)函數(shù)的執(zhí)行代碼是明確的,在編譯時(shí)已被替換,沒(méi)有多態(tài)性的特征 析構(gòu)函數(shù)可以是虛函數(shù),且往往被定義為虛函數(shù)。一般來(lái)說(shuō),若某類中有虛函數(shù),則其析構(gòu)函數(shù)也應(yīng)當(dāng)定義為虛函數(shù)虛 析 構(gòu) 函 數(shù)申明格式virtual ();必要性實(shí)例若析構(gòu)函數(shù)并非虛函數(shù) stu是一個(gè)指向基類的指針變量,指向new開(kāi)辟的空間 new開(kāi)辟的空間是按照派生類doctor開(kāi)辟的,所以除了name、ID之外,還為major、advisor、score申請(qǐng)了空間 delete stu僅僅調(diào)用了基類student的析構(gòu)函數(shù),僅僅釋放name、
60、ID的空間,而沒(méi)有釋放major、advisor、score的空間student student * *stu = stu = new doctornew doctor; ; /聲明基類指針指向聲明基類指針指向doctordoctor類類stu-print(); stu-print(); / /* *printprint已申明為虛函數(shù)已申明為虛函數(shù)* */ / /stu /stu將調(diào)用將調(diào)用doctordoctor的的printprintdelet stu;delet stu;return 0;return 0;純 虛 函 數(shù) 實(shí)例分析 福州大學(xué)中的學(xué)生總共就3類(bachelor、master、doctor),它們的共有基類student實(shí)際上是不需要實(shí)例化為任何對(duì)象的,因此student其實(shí)無(wú)需為虛函數(shù)print定義具體的實(shí)現(xiàn) 盡管基類本
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度重點(diǎn)工程項(xiàng)目安全管理員服務(wù)協(xié)議
- 《幼兒教育行業(yè)分析》課件
- 二零二五年度標(biāo)志設(shè)計(jì)知識(shí)產(chǎn)權(quán)授權(quán)與合同終止協(xié)議3篇
- 二零二五年度陵園用地使用許可協(xié)議3篇
- 二零二五年抵債協(xié)議書(債權(quán)擔(dān)保)詳細(xì)定制3篇
- 二零二五年度鋼筋行業(yè)購(gòu)銷合同規(guī)范范本6篇
- 二零二五版企業(yè)并購(gòu)合同中必須注意的十個(gè)關(guān)鍵細(xì)節(jié)3篇
- 二零二五年建筑拆除與環(huán)?;厥辗职贤侗?篇
- 二零二五年度鞋業(yè)供應(yīng)鏈金融購(gòu)銷合同風(fēng)險(xiǎn)控制協(xié)議
- 二零二五年高新技術(shù)園區(qū)環(huán)境與職業(yè)健康安全治理合同3篇
- 2024年長(zhǎng)春醫(yī)學(xué)高等??茖W(xué)校單招職業(yè)適應(yīng)性測(cè)試題庫(kù)及答案解析
- 品質(zhì)部組織架構(gòu)圖構(gòu)
- 解析幾何-2023上海市高三數(shù)學(xué)一模匯編【教師版】
- 項(xiàng)目維修維保方案
- 上海市浦東新區(qū)2023-2024學(xué)年一年級(jí)上學(xué)期期末考試數(shù)學(xué)試題
- 插圖在小學(xué)英語(yǔ)口語(yǔ)教學(xué)中的運(yùn)用
- 前列腺增生藥物治療
- 人工智能知識(shí)圖譜(歸納導(dǎo)圖)
- 滴滴補(bǔ)貼方案
- 民宿建筑設(shè)計(jì)方案
- 干部基本信息審核認(rèn)定表
評(píng)論
0/150
提交評(píng)論