九九热最新网址,777奇米四色米奇影院在线播放,国产精品18久久久久久久久久,中文有码视频,亚洲一区在线免费观看,国产91精品在线,婷婷丁香六月天

譚浩強(qiáng)版《C++程序設(shè)計(jì)》第9章.ppt

上傳人:xt****7 文檔編號:20379914 上傳時間:2021-03-14 格式:PPT 頁數(shù):89 大?。?76.50KB
收藏 版權(quán)申訴 舉報 下載
譚浩強(qiáng)版《C++程序設(shè)計(jì)》第9章.ppt_第1頁
第1頁 / 共89頁
譚浩強(qiáng)版《C++程序設(shè)計(jì)》第9章.ppt_第2頁
第2頁 / 共89頁
譚浩強(qiáng)版《C++程序設(shè)計(jì)》第9章.ppt_第3頁
第3頁 / 共89頁

下載文檔到電腦,查找使用更方便

14.9 積分

下載資源

還剩頁未讀,繼續(xù)閱讀

資源描述:

《譚浩強(qiáng)版《C++程序設(shè)計(jì)》第9章.ppt》由會員分享,可在線閱讀,更多相關(guān)《譚浩強(qiáng)版《C++程序設(shè)計(jì)》第9章.ppt(89頁珍藏版)》請?jiān)谘b配圖網(wǎng)上搜索。

1、第 9章 關(guān)于類和對象的進(jìn)一步討論 9.1 構(gòu)造函數(shù) 9.2 析構(gòu)函數(shù) 9.3 調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)的順序 9.4 對象數(shù)組 9.5 對象指針 9.6 共用數(shù)據(jù)的保護(hù) 9.7 對象的動態(tài)建立和釋放 9.8 對象的賦值和復(fù)制 9.9 靜態(tài)成員 9.10 友元 9.11 類模板 在建立一個對象時 ,作某些初始化的工作如 對數(shù)據(jù) 成員賦初值 。即在 創(chuàng)建對象(分配內(nèi)存時)進(jìn)行數(shù) 據(jù)成員的初始化 ,因?yàn)閷ο笫菍?shí)實(shí)在在的對象,不 能無具體屬性值。 注意: 類的數(shù)據(jù)成員是不能在聲明類時初始化的 。 9.1 構(gòu)造函數(shù) 作用: 創(chuàng)建對象(分配內(nèi)存時)時進(jìn)行數(shù)據(jù) 成員的初始化 9.1.1 對象的初始化 如果一

2、個類中所有的成員都是公用的,則可以在定 義對象時對數(shù)據(jù)成員進(jìn)行初始化。如 class Time public: /聲明為公用成員 hour; minute; sec; ; Time t1=14,56,30; /將 t1初始化為 14:56:30 但是, 一般數(shù)據(jù)成員是私有的,或者類中有 private 或 protected的成員,就不能用這種方法初始化 。 如何實(shí)現(xiàn)? C+提供了構(gòu)造函數(shù) (constructor)來處理對象的初 始化。 構(gòu)造函數(shù)是特殊的成員函數(shù),與其他成員函數(shù)不 同, 不需要用戶來調(diào)用它,而是在建立對象時自動 執(zhí)行 。 構(gòu)造函數(shù)的 名字必須與類名同名 ,而不能由用戶 任意命

3、名,以便編譯系統(tǒng)能識別它并把它作為構(gòu)造 函數(shù)處理。 它不具有任何類型,不返回任何值 。 構(gòu)造函數(shù)的功能是由用戶定義的, 用戶根據(jù)初始 化的要求設(shè)計(jì)函數(shù)體和函數(shù)參數(shù) 。 9.1.2 構(gòu)造函數(shù)的作用 例 9.1 在例 8.3基礎(chǔ)上定義構(gòu)造成員函數(shù)。 #include using namespace std; class Time public: Time( ) /定義構(gòu)造成員函數(shù),函數(shù)名與類名相同 hour=0; /利用構(gòu)造函數(shù)對對象中的數(shù)據(jù)成員賦初值 minute=0; sec=0; void set_time( ); /函數(shù)聲明 void show_time( ); /函數(shù)聲明 private

4、: int hour; /私有數(shù)據(jù)成員 int minute; int sec; ; void Time set_time( ) /定義成員函數(shù),向數(shù)據(jù)成員賦值 cinhour; cinminute; cinsec; void Time show_time( ) /定義成員函數(shù),輸出數(shù)據(jù)成員的值 couthour:minute:secendl; int main( ) Time t1; /建立對象 t1, 同時調(diào)用構(gòu)造函數(shù) t1.Time( ) t1.set_time( ); /對 t1的數(shù)據(jù)成員賦值 t1.show_time( ); /顯示 t1的數(shù)據(jù)成員的值 Time t2; /建立對象

5、t2, 同時調(diào)用構(gòu)造函數(shù) t2.Time( ) t2.show_time( ); /顯示 t2的數(shù)據(jù)成員的值 return 0; 程序運(yùn)行的情況為: 10 25 54 (從鍵盤輸入新值賦給 t1的數(shù)據(jù)成員 ) 10:25:54 (輸出 t1的時、分、秒值 ) 0:0:0 (輸出 t2的時、分、秒值 ) 也可以 在類外定義構(gòu)造函數(shù): Time Time( ) /要加上類名 Time和域限定 符 “ ” hour=0; minute=0; sec=0; 有關(guān)構(gòu)造函數(shù)的使用,有以下說明: (1) 在類對象進(jìn)入其作用域時調(diào)用構(gòu)造函數(shù)。 (2) 構(gòu)造函數(shù)沒有返回值,因此也不需要在定義構(gòu) 造函數(shù)時聲明類型

6、,這是它和一般函數(shù)的一個重要 的不同之點(diǎn)。 (3) 構(gòu)造函數(shù) 不需用戶調(diào)用 ,也不能被用戶調(diào)用。 (4) 如果用戶自己沒有定義構(gòu)造函數(shù),則 C+系統(tǒng) 會自動生成一個構(gòu)造函數(shù),只是這個構(gòu)造函數(shù)的函 數(shù)體是空的,也沒有參數(shù),不執(zhí)行初始化操作。 不帶參數(shù)構(gòu)造函數(shù), 這種方式使該類的每一個對 象都得到同一組初值。 帶參數(shù)的構(gòu)造函數(shù),用戶希望對不同的對象賦予 不同的初值 。 構(gòu)造函數(shù)首部的一般格式: 構(gòu)造函數(shù)名 (類型 1 形參 1,類型 2 形參 2, ) 實(shí)參是在定義對象時給出的 。 定義對象的一般格式為 : 類名 對象名 (實(shí)參 1,實(shí)參 2, ); 9.1.3 帶參數(shù)的構(gòu)造函數(shù) 例 9.2 有兩

7、個長方柱,其長、寬、高分別為: (1)12,20,25; (2)10,14,20。求它們的體積。編一個 基于對象的程序,在類中用帶參數(shù)的構(gòu)造函數(shù)。 #include using namespace std; class Box public: Box(int,int,int); /聲明帶參數(shù)的構(gòu)造函數(shù) int volume( ); /聲明計(jì)算體積的函數(shù) private: int height; int width; int length; ; Box Box(int h,int w,int len) /在類外定義帶參數(shù)的構(gòu)造函數(shù) height=h; width=w; length=len; i

8、nt Box volume( ) /定義計(jì)算體積的函數(shù) return(height*width*length); int main( ) Box box1(12,25,30); /建立對象 box1, 并指定 box1長、寬、高的值 coutThe volume of box1 is box1.volume( )endl; Box box2(15,30,21); /建立對象 box2, 并指定 box2長、寬、高的值 coutThe volume of box2 is box2.volume( )endl; return 0; 程序運(yùn)行結(jié)果如下: The volume of box1 is 9

9、000 The volume of box2 is 9450 注意 : 帶參數(shù)的構(gòu)造函數(shù)中的形參, 其對應(yīng)的實(shí)參在定義 對象時給定。 C+還提供另一種初始化數(shù)據(jù)成員的方法 參數(shù) 初始化表 來實(shí)現(xiàn)對數(shù)據(jù)成員的初始化。 這種方法不在函數(shù)體內(nèi)對數(shù)據(jù)成員初始化,而是在 函數(shù)首部實(shí)現(xiàn)。 例如例 9.2中定義構(gòu)造函數(shù)可以改 用以下形式: Box Box(int h,int w,int len):height(h), width(w), length(len) 這種寫法方便、簡練,尤其當(dāng)需要初始化的數(shù)據(jù)成 員較多時更顯其優(yōu)越性。 甚至可以直接在類體中 (而不是在類外 )定義構(gòu)造函數(shù)。 9.1.4 用參數(shù)初始

10、化表對數(shù)據(jù)成員初始化 在一個類中可以定義多個構(gòu)造函數(shù),以便對類對 象提供不同的初始化的方法,供用戶選用。 這些構(gòu)造函數(shù)具有相同的名字,而參數(shù)的個數(shù)或 參數(shù)的類型不相同。這稱為 構(gòu)造函數(shù)的重載 。 在第 4章第 4.6節(jié)中所介紹的函數(shù)重載的知識也適用 于構(gòu)造函數(shù)。 通過下面的例子可以了解怎樣應(yīng)用構(gòu)造函數(shù)的重載。 9.1.5 構(gòu)造函數(shù)的重載 例 9.3 在例 9.2的基礎(chǔ)上,定義兩個構(gòu)造函數(shù),其中 一個無參數(shù),一個有參數(shù)。 #include using namespace std; class Box public: Box( ); /聲明一個無參的構(gòu)造函數(shù) Box(int h,int w,int

11、 len):height(h),width(w),length(len) /聲明一個有參的構(gòu)造函數(shù),用參數(shù)的初始化表對數(shù)據(jù)成員初始化 int volume( ); private: int height; int width; int length; ; Box Box( ) /定義一個無參的構(gòu)造函數(shù) height=10; width=10; length=10; int Box volume( ) return(height*width*length); int main( ) Box box1; /建立對象 box1,不指定實(shí)參 coutThe volume of box1 is box1

12、.volume( )endl; Box box2(15,30,25); /建立對象 box2,指定 3個實(shí)參 coutThe volume of box2 is box2.volume( )endl; return 0; 在本程序中定義了兩個重載的構(gòu)造函數(shù), 其實(shí)還可 以定義其他重載構(gòu)造函數(shù) 。 說明: (1) 調(diào)用構(gòu)造函數(shù)時不必給出實(shí)參的構(gòu)造函數(shù),稱 為 默認(rèn)構(gòu)造函數(shù) (default constructor)。 顯然,無參 的構(gòu)造函數(shù)屬于默認(rèn)構(gòu)造函數(shù)。一個類只能有一個 默認(rèn)構(gòu)造函數(shù)。 (2) 如果在建立對象時選用的是無參構(gòu)造函數(shù),應(yīng) 注意正確書寫定義對象的語句。 (3) 盡管在一個類中可以

13、包含多個構(gòu)造函數(shù),但是 對于每一個對象來說, 建立對象時只執(zhí)行其中一個 構(gòu)造函數(shù) ,并非每個構(gòu)造函數(shù)都被執(zhí)行。 構(gòu)造函數(shù)中參數(shù)的值既可以通過實(shí)參傳遞,也可以 指定為某些默認(rèn)值,即 如果用戶不指定實(shí)參值,編 譯系統(tǒng)就使形參取默認(rèn)值 。 例 9.4 將例 9.3程序中的構(gòu)造函數(shù)改用含默認(rèn)值的參 數(shù),長、寬、高的默認(rèn)值均為 10。 在例 9.3程序的基礎(chǔ)上改寫如下: 9.1.6 使用默認(rèn)參數(shù)的構(gòu)造函數(shù) #include using namespace std; class Box public: Box(int h=10,int w=10,int len=10); /在聲明構(gòu)造函數(shù)時指定默認(rèn)參數(shù) i

14、nt volume( ); private: int height; int width; int length; ; Box Box(int h,int w,int len) /在定義函數(shù)時可以不指定默認(rèn)參數(shù) height=h; width=w; length=len; int Box volume( ) return(height*width*length); int main( ) Box box1; /沒有給實(shí)參 coutThe volume of box1 is box1.volume( )endl; Box box2(15); /只給定一個實(shí)參 coutThe volume of

15、box2 is box2.volume( )endl; Box box3(15,30); /只給定 2個實(shí)參 coutThe volume of box3 is box3.volume( )endl; Box box4(15,30,20); /給定 3個實(shí)參 coutThe volume of box4 is box4.volume( )endl; return 0; 析構(gòu)函數(shù) (destructor)也是一個特殊的成員函數(shù),它 的作用與構(gòu)造函數(shù)相反,它的 名字是類名的前面加 一個“”符號 。在 C+中 “ ” 是位取反運(yùn)算符, 從這點(diǎn)也可以想到: 析構(gòu)函數(shù)是與構(gòu)造函數(shù)作用 相反的函數(shù)。 當(dāng)對

16、象的生命期結(jié)束時,會自動執(zhí)行析構(gòu)函數(shù) 。 如果在一個函數(shù)中定義了一個對象 (它是自動局 部對象 ),當(dāng)這個函數(shù)被調(diào)用結(jié)束時,對象應(yīng)該釋 放, 在對象釋放前自動執(zhí)行析構(gòu)函數(shù)。 9.2 析構(gòu)函數(shù) static局部對象 ,只在 main函數(shù)結(jié)束或調(diào)用 exit函 數(shù)結(jié)束程序時,才調(diào)用 static局部對象的析構(gòu)函數(shù)。 全局對象 ,則在程序的流程離開其作用域時 (如 main函數(shù)結(jié)束或調(diào)用 exit函數(shù) ) 時,調(diào)用該全局對 象的析構(gòu)函數(shù)。 如果用 new運(yùn)算符 動態(tài)地建立了一個對象 ,當(dāng)用 delete運(yùn)算符釋放該對象時,先調(diào)用該對象的析構(gòu) 函數(shù)。 析構(gòu)函數(shù)的作用: 并不是刪除對象,而是在撤銷對 象

17、占用的內(nèi)存之前完成一些清理工作,使這部分內(nèi) 存可以被程序分配給新對象使用 。 程序設(shè)計(jì)者事先設(shè)計(jì)好析構(gòu)函數(shù),只要對象的生命 期結(jié)束,程序就自動執(zhí)行析構(gòu)函數(shù)來完成這些工作。 析構(gòu)函數(shù)不返回任何值,沒有函數(shù)類型,也沒有函 數(shù)參數(shù)。 因此它不能被重載 。 一個類可以有多個構(gòu) 造函數(shù),但只能有一個析構(gòu)函數(shù)。 析構(gòu)函數(shù)的作用 并不僅限于釋放資源 方面,它還 可以 輸出有關(guān)的信息 。 一般情況下,類的設(shè)計(jì)者應(yīng)當(dāng)在聲明類的同時定義 析構(gòu)函數(shù),以指定如何完成 “ 清理 ” 的工作。 如果用戶沒有定義析構(gòu)函數(shù), C+編譯系統(tǒng)會自動 生成一個析構(gòu)函數(shù),但它只是徒有析構(gòu)函數(shù)的名稱 和形式, 實(shí)際上什么操作都不進(jìn)行

18、。想讓析構(gòu)函數(shù) 完成任何工作,都必須在定義的析構(gòu)函數(shù)中指定。 例 9.5 包含構(gòu)造函數(shù)和析構(gòu)函數(shù)的 C+程序。 #include #include using namespace std; class Student /聲明 Student類 public: student(int n,string nam,char s ) /定義構(gòu)造函數(shù) num=n; name=nam; sex=s; coutConstructor called.endl; /輸出有關(guān)信息 Student( ) /定義析構(gòu)函數(shù) coutDestructor called.endl; /輸出有關(guān)信息 void display

19、( ) /定義成員函數(shù) coutnum: numendl; coutname: nameendl; coutsex: sexendlendl; private: int num; char name10; char sex; ; int main( ) Student stud1(10010,Wang_li,f); / 建立對象 stud1 stud1.display( ); /輸出學(xué)生 1的數(shù)據(jù) Student stud2(10011,Zhang_fun,m); /定義對象 stud2 stud2.display( ); /輸出學(xué)生 2的數(shù)據(jù) return 0; 程序運(yùn)行結(jié)果如下: Cons

20、tructor called. (執(zhí)行 stud1的構(gòu)造函數(shù) ) num: 10010 (執(zhí)行 stud1的 display函數(shù) ) name:Wang_li sex: f Constructor called. (執(zhí)行 stud2的構(gòu)造函數(shù) ) num: 10011 (執(zhí)行 stud2的 display函數(shù) ) name:Zhang_fun sex:m Destructor called. (執(zhí)行 stud2的析構(gòu)函數(shù) ) Destructor called. (執(zhí)行 stud1的析構(gòu)函數(shù) ) 在使用構(gòu)造函數(shù)和析構(gòu)函數(shù)時,需要特別注意對它 們的調(diào)用時間和調(diào)用順序。 在一般情況下, 調(diào)用析構(gòu)函

21、數(shù)的次序正好與調(diào)用構(gòu) 造函數(shù)的次序相反: 最先被調(diào)用的構(gòu)造函數(shù),其 對應(yīng)的 (同一對象中的 )析構(gòu)函數(shù)最后被調(diào)用,而最 后被調(diào)用的構(gòu)造函數(shù),其對應(yīng)的析構(gòu)函數(shù)最先被調(diào) 用。如圖 9.1示意。 9.3 調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)的順序 圖 9.1 但是,并不是在任何情況下都是按這一原則處理的。 對象可以在不同的作用域中定義,可以有不同的存 儲類別。這些會影響調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)的時 機(jī)。 下面歸納一下什么時候調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù): (1) 在全局范圍中定義的對象 它的構(gòu)造函數(shù)在文件中的所有函數(shù) (包括 main函數(shù) ) 執(zhí)行之前調(diào)用。當(dāng) main函數(shù)執(zhí)行完畢或調(diào)用 exit函 數(shù)時 (此時程序終止

22、 ),調(diào)用析構(gòu)函數(shù)。 (2) 如果定義的是局部自動對象 (例如在函數(shù)中定義 對象 ),則在建立對象時調(diào)用其構(gòu)造函數(shù)。如果函 數(shù)被多次調(diào)用,則在每次建立對象時都要調(diào)用構(gòu)造 函數(shù)。在函數(shù)調(diào)用結(jié)束、對象釋放時先調(diào)用析構(gòu)函 數(shù)。 (3) 如果在函數(shù)中定義靜態(tài) (static)局部對象,則只 在程序第一次調(diào)用此函數(shù)建立對象時調(diào)用構(gòu)造函數(shù) 一次,只在 main函數(shù)結(jié)束或調(diào)用 exit函數(shù)結(jié)束程序 時,才調(diào)用析構(gòu)函數(shù)。 數(shù)組也可以由對象組成 (對象數(shù)組的每一個元素都 是同類的對象 )。 例如一個班有 50個學(xué)生,每個學(xué)生的屬性包括姓名、 性別、年齡、成績等。如果為每一個學(xué)生建立一個 對象,需要分別取 50個

23、對象名。用程序處理很不方 便。這時可以定義一個 “ 學(xué)生類 ” 對象數(shù)組,每一 個數(shù)組元素是一個 “ 學(xué)生類 ” 對象。例如 Student stud50; /假設(shè)已聲明了 Student類,定義 stud數(shù)組,有 50個元素 9.4 對象數(shù)組 在建立數(shù)組時,同樣要調(diào)用構(gòu)造函數(shù)。如果有 50個 元素,需要調(diào)用 50次構(gòu)造函數(shù)。 如果構(gòu)造函數(shù)有多個參數(shù),則不能用在定義數(shù)組時 直接提供所有實(shí)參的方法,因?yàn)橐粋€數(shù)組有多個元 素,對每個元素要提供多個實(shí)參,如果再考慮到構(gòu) 造函數(shù)有默認(rèn)參數(shù)的情況,很容易造成實(shí)參與形參 的對應(yīng)關(guān)系不清晰,出現(xiàn)歧義性。 如果構(gòu)造函數(shù)有多個參數(shù),在定義對象數(shù)組時應(yīng)當(dāng) 怎樣實(shí)現(xiàn)

24、初始化呢? 在花括號中分別寫出構(gòu)造函數(shù)并指定實(shí)參。如果構(gòu) 造函數(shù)有 3個參數(shù),分別代表學(xué)號、年齡、成績。 則可以這樣定義對象數(shù)組: Student Stud3= /定義對象數(shù)組 Student(1001,18,87), /調(diào)用第 1個元素的構(gòu)造函數(shù),為它提 供 3個實(shí)參 Student(1002,19,76), /調(diào)用第 2個元素的構(gòu)造函數(shù),為它提 供 3個實(shí)參 Student(1003,18,72) /調(diào)用第 3個元素的構(gòu)造函數(shù),為它提 供 3個實(shí)參 ; 在建立對象數(shù)組時,分別調(diào)用構(gòu)造函數(shù),對每個元 素初始化。每一個元素的實(shí)參分別用括號包起來, 對應(yīng)構(gòu)造函數(shù)的一組形參,不會混淆。 例 9.6

25、 對象數(shù)組的使用方法。 #include using namespace std; class Box public: Box(int h=10,int w=12,int len=15): height(h),width(w),length(len) /聲明有默認(rèn)參數(shù)的構(gòu)造函數(shù),用參數(shù)初始化表對數(shù)據(jù)成員初始 化 int volume( ); private: int height; int width; int length; ; int Box volume( ) return(height*width*length); int main( ) Box a3= /定義對象數(shù)組 Box(10,

26、12,15), /調(diào)用構(gòu)造函數(shù) Box, 提供第 1個元素的實(shí)參 Box(15,18,20), /調(diào)用構(gòu)造函數(shù) Box, 提供第 2個元素的實(shí)參 Box(16,20,26) /調(diào)用構(gòu)造函數(shù) Box, 提供第 3個元素的實(shí)參 ; coutvolume of a0 is a0.volume( )endl; coutvolume of a1 is a1.volume( )endl; coutvolume of a2 is a2.volume( )endl; 運(yùn)行結(jié)果如下: volume of a0 is 1800 volume of a1 is 5400 volume of a2 is 8320 在

27、建立對象時,編譯系統(tǒng)會為每一個對象分配一定 的存儲空間,以存放其成員。 對象空間的起始地址 就是對象的指針 ??梢远x一個指針變量,用來存 放對象的指針。如果有一個類: class Time public: int hour; int minute; int sec; void get_time( ); ; 9.5 對象指針 9.5.1 指向?qū)ο蟮闹羔?void Time get_time( ) couthour:minute:sechour pt所指向的對象中的 hour成員,即 t1.hour (*pt).get_time ( ) 調(diào)用 pt所指向的對象中的 get_time函數(shù),即 t1

28、.get_time pt-get_time ( ) 調(diào)用 pt所指向的對象中的 get_time函數(shù),即 t1.get_time 對象有地址,存放對象初始地址的指針變量就是指 向?qū)ο蟮闹羔樧兞?。對象中的成員也有地址,存放 對象成員地址的指針變量就是指向?qū)ο蟪蓡T的指針 變量。 9.5.2 指向?qū)ο蟪蓡T的指針 1. 指向?qū)ο髷?shù)據(jù)成員的指針 定義指向?qū)ο髷?shù)據(jù)成員的指針變量的方法和 定義指 向普通變量的指針變量方法相同 。例如 int *p1; /定義指向整型數(shù)據(jù)的指針變量 定義指向?qū)ο髷?shù)據(jù)成員的指針變量的一般形式為 數(shù)據(jù)類型名 *指針變量名; 如果 Time類的數(shù)據(jù)成員 hour為 公用的 整型數(shù)據(jù)

29、, 則 可以在類外 通過指向?qū)ο髷?shù)據(jù)成員的指針變量訪 問對象數(shù)據(jù)成員 hour。 p1= /將對象 t1的數(shù)據(jù)成員 hour的地址賦給 p1, p1指向 t1.hour cout*p1endl; /輸出 t1.hour的值 例 9.7 有關(guān)對象指針的使用方法。 #include using namespace std; class Time public: Time(int,int,int); int hour; int minute; int sec; void get_time( ); /聲明公有成員函數(shù) ; Time Time(int h,int m,int s) hour=h; min

30、ute=m; sec=s; void Time get_time( ) /定義公有成員函數(shù) couthour:minute: secendl; int main( ) Time t1(10,13,56); /定義 Time類對象 t1 int *p1= /定義指向整型數(shù)據(jù)的指針變量 p1, 并使 p1指 向 t1.hour cout*p1get_time( ); /調(diào)用 p2所指向?qū)ο?(即 t1)的 get_time函數(shù) 每個對象中的數(shù)據(jù)成員都分別占有存儲空間,如果 對同一個類定義了 n個對象,則有 n組同樣大小的空 間以存放 n個對象中的數(shù)據(jù)成員。但是,不同對象 都調(diào)用同一個函數(shù)代碼段。

31、那么,當(dāng)不同對象的成員函數(shù)引用數(shù)據(jù)成員時,怎 么能保證引用的是所指定的對象的數(shù)據(jù)成員呢? 9.5.3 this 指針 在每一個成員函數(shù)中都包含一個特殊的指針,這個 指針的名字是固定的,稱為 this。 它是指向本類對象的指針,它的值是當(dāng)前被調(diào)用的 成員函數(shù)所在的對象的起始地址 。例如,當(dāng)調(diào)用成 員函數(shù) a.volume時,編譯系統(tǒng)就把對象 a的起始地 址賦給 this指針,于是在成員函數(shù)引用數(shù)據(jù)成員時, 就按照 this的指向找到對象 a的數(shù)據(jù)成員。例如 volume函數(shù)要計(jì)算 height*width*length的值,實(shí)際 上是執(zhí)行: (this-height)*(this-width)*

32、(this-length) 由于當(dāng)前 this指向 a, 因此相當(dāng)于執(zhí)行: (a.height)*(a.width)*(a.length) 這就計(jì)算出長方體 a的體積。 this指針是隱式使用的,它是作為參數(shù)被傳遞給成 員函數(shù)的 。本來,成員函數(shù) volume的定義如下: int Box volume( ) return (height*width*length); C+把它處理為 int Box volume(Box *this) return(this-height * this-width * this-length); 即在成員函數(shù)的形參表列中增加一個 this指針。在 調(diào)用該成員函數(shù)

33、時,實(shí)際上是用以下方式調(diào)用的: a.volume( 將對象 a的地址傳給形參 this指針。然后按 this的指 向去引用其他成員。 需要說明: 這些都是編譯系統(tǒng)自動實(shí)現(xiàn)的,編程 序者不必人為地在形參中增加 this指針,也不必將 對象 a的地址傳給 this指針。 在需要時也可以顯式地使用 this指針 。例如在 Box 類的 volume函數(shù)中,下面兩種表示方法都是合法的、 相互等價的。 return(height * width * length); /隱含使用 this指針 return(this-height * this-width * this-length); /顯式使用 th

34、is指針 可以用 *this表示被調(diào)用的成員函數(shù)所在的對象, *this就是 this所指向的對象,即當(dāng)前的對象。 例如 在成員函數(shù) a.volume( )的函數(shù)體中,如果出現(xiàn) *this, 它就是本對象 a。 上面的 return語句也可寫成 return(*this).height * (*this).width * (*this).length); 注意 *this兩側(cè)的括號不能省略,不能寫成 *this.height。 所謂 “ 調(diào)用對象 a的成員函數(shù) f”, 實(shí)際上是在調(diào)用 成員函數(shù) f時使 this指針指向?qū)ο?a, 從而訪問對象 a 的成員。在使用 “ 調(diào)用對象 a的成員函數(shù) f

35、”時,應(yīng) 當(dāng)對它的含義有正確的理解。 有時人們希望在需要用到對象時才建立對象,在不 需要用該對象時就撤銷它,釋放它所占的內(nèi)存空間 以供別的數(shù)據(jù)使用。這樣 可提高內(nèi)存空間的利用率 。 用 new運(yùn)算符動態(tài)建立對象,用 delete運(yùn)算符撤銷 對象。 如果已經(jīng)定義了一個 Box類,可以用下面的方法動 態(tài)地建立一個對象: 9.7 對象的動態(tài)建立和釋放 new Box; 編譯系統(tǒng)開辟了一段內(nèi)存空間,并在此內(nèi)存空間中 存放一個 Box類對象,同時調(diào)用該類的構(gòu)造函數(shù), 以使該對象初始化 (如果已對構(gòu)造函數(shù)賦予此功能 的話 )。但是此時用戶還無法訪問這個對象,因?yàn)?這個對象既沒有對象名,用戶也不知道它的地址

36、。 這種對象稱為 無名對象 ,它確實(shí)是存在的,但它沒 有名字。 用 new運(yùn)算符動態(tài)地分配內(nèi)存后,將返回一個指向 新對象的指針的值,即所分配的內(nèi)存空間的起始地 址。用戶 需要定義一個指向本類的對象的指針變量 來存放該地址 。如 Box *pt; /定義一個指向 Box類對象的指針變量 pt pt=new Box; /在 pt中存放了新建對象的起始地址 在程序中就可以通過 pt訪問這個新建的對象。如 coutheight; /輸出該對象的 height成員 coutvolume( ); /調(diào)用該對象的 volume函數(shù),計(jì)算并輸出體積 C+還 允許在執(zhí)行 new時,對新建立的對象進(jìn)行初 始化。

37、如 (調(diào)帶參數(shù)的構(gòu)造函數(shù)) Box *pt=new Box(12,15,18); 這種寫法是把上面兩個語句 (定義指針變量和用 new 建立新對象 )合并為一個語句,并指定初值。這樣 更精煉。新對象中的 height, width和 length分別獲 得初值 12,15,18。 調(diào)用對象既可以通過對象名,也可以通過指針 。用 new建立的動態(tài)對象一般是不用對象名的,是通過 指針訪問的,它主要應(yīng)用于動態(tài)的數(shù)據(jù)結(jié)構(gòu),如鏈 表。訪問鏈表中的結(jié)點(diǎn),并不需要通過對象名 , 在執(zhí)行 new運(yùn)算時,如果內(nèi)存量不足,無法開辟所 需的內(nèi)存空間,目前大多數(shù) C+編譯系統(tǒng)都使 new 返回一個 0指針值。 只要檢

38、測返回值是否為 0,就可 判斷分配內(nèi)存是否成功。 在不再需要使用由 new建立的對象時,可以用 delete運(yùn)算符予以 釋放 。如 delete pt; /釋放 pt指向的內(nèi)存空間 這就撤銷了 pt指向的對象。 在執(zhí)行 delete運(yùn)算符時,在釋放內(nèi)存空間之前,自 動 調(diào)用析構(gòu)函數(shù) ,完成有關(guān)善后清理工作 。 如果對一個類定義了兩個或多個對象,則這些 同類 的對象之間可以互相賦值 ,即一個對象的值可以賦 給另一個同類的對象。 對象的值是指對象中所有數(shù) 據(jù)成員的值 。 對象之間的賦值也是通過賦值運(yùn)算符 “ =” 進(jìn)行的。 本來,賦值運(yùn)算符 “ =” 只能用來對單個的變量賦 值,現(xiàn)在被 擴(kuò)展為兩個

39、同類對象之間的賦值,這是 通過對 賦值運(yùn)算符的重載 實(shí)現(xiàn)的 。實(shí)際這個過程是 通過成員復(fù)制來完成的,即將一個對象的成員值一 一復(fù)制給另一對象的對應(yīng)成員。 9.8 對象的賦值和復(fù)制 COPY 9.8.1 對象的賦值 對象名 1 = 對象名 2; 注意對象名 1和對象名 2必須屬于同一個類 。 例如 Student stud1,stud2; /定義兩個同類的對象 stud2=stud1; /將 stud1賦給 stud2 通過下面的例子可以了解怎樣進(jìn)行對象的賦值。 例 9.9 對象的賦值。 #include using namespace std; class Box public: Box(in

40、t=10,int=10,int=10); /聲明有默認(rèn)參數(shù)的構(gòu)造函數(shù) int volume( ); private: int height; int width; int length; ; Box Box(int h,int w,int len) height=h; width=w; length=len; int Box volume( ) return(height*width*length); /返回體積 int main( ) Box box1(15,30,25),box2; /定義兩個對象 box1和 box2 coutThe volume of box1 is box1.volu

41、me( )endl; box2=box1; /將 box1的值賦給 box2 coutThe volume of box2 is box2.volume( )endl; return 0; 運(yùn)行結(jié)果如下: The volume of box1 is 11250 The volume of box2 is 11250 說明: (1) 對象的賦值只對其中的數(shù)據(jù)成員賦值,而不對 成員函數(shù)賦值。 (2) 類的數(shù)據(jù)成員中 不能包括動態(tài)分配的數(shù)據(jù),否 則在賦值時可能出現(xiàn)嚴(yán)重后果 。 有時需要用到多個完全相同的對象。此外,有時需 要將對象在某一瞬時的狀態(tài)保留下來。這就是對象 的復(fù)制機(jī)制。 用一個已有的對象快

42、速地復(fù)制出多個 完全相同的對象 。如 Box box2(box1); 其作用是用已有的對象 box1去克隆出一個新對象 box2。 其一般形式為 類名 對象 2(對象 1); 用對象 1復(fù)制出對象 2。 9.8.2 對象的復(fù)制 可以看到: 它與前面介紹過的定義對象方式類似, 但是 括號中給出的參數(shù)不是一般的變量,而是對象 。 在建立對象時 調(diào)用一個特殊的構(gòu)造函數(shù) 復(fù)制構(gòu) 造函數(shù) (copy constructor)。 這個函數(shù)的形式是這樣 的: /The copy constructor definition. Box Box(const Box width=b.width; length=b

43、.length; 復(fù)制構(gòu)造函數(shù)也是構(gòu)造函數(shù),但它只有一個參數(shù), 這個參數(shù)是本類的對象 (不能是其他類的對象 ),而 且采用對象的引用的形式 (一般約定加 const聲明, 使參數(shù)值不能改變,以免在調(diào)用此函數(shù)時因不慎而 使對象值被修改 )。 此復(fù)制構(gòu)造函數(shù)的 作用就是將實(shí)參對象的各成員值 一一賦給新的對象中對應(yīng)的成員 。 回顧復(fù)制對象的語句 Box box2(box1); 這實(shí)際上也是建立對象的語句,建立一個新對象 box2。 由于在括號內(nèi)給定的實(shí)參是對象,因此編譯 系統(tǒng)就調(diào)用復(fù)制構(gòu)造函數(shù) (它的形參也是對象 ),而 不會去調(diào)用其他構(gòu)造函數(shù)。 實(shí)參 box1的地址傳遞給 形參 b(b是 box1

44、的引用 ),因此執(zhí)行復(fù)制構(gòu)造函數(shù)的 函數(shù)體時,將 box1對象中各數(shù)據(jù)成員的值賦給 box2 中各數(shù)據(jù)成員。 如果用戶自己未定義復(fù)制構(gòu)造函數(shù),則編譯系統(tǒng)會 自動提供一個默認(rèn)的復(fù)制構(gòu)造函數(shù) , 其作用只是簡 單地復(fù)制類中每個數(shù)據(jù)成員。 C+還提供另一種方便用戶的復(fù)制形式,用賦值號 代替括號 ,如 Box box2=box1; /用 box1初始化 box2 其一般形式為 類名 對象名 1 = 對象名 2; 可以在一個語句中進(jìn)行多個對象的復(fù)制。如 Box box2=box1,box3=box2; 按 box1來復(fù)制 box2和 box3。 可以看出: 這種形式 與變量初始化語句類似,請與下面定義變

45、量的語句 作比較: int a=4,b=a; 這種形式看起來很直觀,用起來很方便。 但是其作 用都是調(diào)用復(fù)制構(gòu)造函數(shù)。 請注意對象的復(fù)制和對象的賦值在概念上和語法上 的區(qū)別 。對象的賦值是對一個已經(jīng)存在的對象賦值, 因此必須先定義被賦值的對象,才能進(jìn)行賦值。而 對象的復(fù)制則是從無到有地建立一個新對象,并使 它與一個已有的對象完全相同 (包括對象的結(jié)構(gòu)和 成員的值 )。 可以對例 9.7程序中的主函數(shù)作一些修改 : int main( ) Box box1(15,30,25); /定義 box1 coutThe volume of box1 is box1.volume( )endl; Box

46、box2=box1,box3=box2; /按 box1來復(fù)制 box2,box3 coutThe volume of box2 is box2.volume( )endl; coutThe volume of box3 is box3.volume( )endl; 執(zhí)行完第 3行后, 3個對象的狀態(tài)完全相同。 請注意普通構(gòu)造函數(shù)和復(fù)制構(gòu)造函數(shù)的區(qū)別 ! (1) 在形式上 類名 (形參表列 ); /普通構(gòu)造函數(shù)的聲明,如 Box(int h,int w,int len); 類名 (類名 /復(fù)制構(gòu)造函數(shù)的聲明,如 Box(Box (2) 在建立對象時,實(shí)參類型不同。系統(tǒng)會根據(jù)實(shí) 參的類型決定調(diào)用

47、普通構(gòu)造函數(shù)或復(fù)制構(gòu)造函數(shù)。 如 Box box1(12,15,16); /實(shí)參為整數(shù),調(diào)用普通構(gòu)造函數(shù) Box box2(box1); /實(shí)參是對象名,調(diào)用復(fù)制構(gòu)造函數(shù) ( 3) 在什么情況下被調(diào)用 普通構(gòu)造函數(shù)在程序中建立對象時被調(diào)用。 復(fù)制構(gòu)造函數(shù)在用已有對象復(fù)制一個新對象時被調(diào) 用, 在以下 3種情況下需要克隆對象 : 程序中需要新建立一個對象,并用另一個同類 的對象對它初始化,如前面介紹的那樣。 當(dāng)函數(shù)的參數(shù)為類的對象時。在調(diào)用函數(shù)時需 要將實(shí)參對象完整地傳遞給形參,也就是需要建立 一個實(shí)參的拷貝,這就是按實(shí)參復(fù)制一個形參,系 統(tǒng)是通過調(diào)用復(fù)制構(gòu)造函數(shù)來實(shí)現(xiàn)的,這樣能保證 形參具有和

48、實(shí)參完全相同的值。如 void fun(Box b) /形參是類的對象 int main( ) Box box1(12,15,18); fun(box1); /實(shí)參是類的對象,調(diào)用函數(shù)時將復(fù)制一個新對象 b return 0; 函數(shù)的返回值是類的對象。在函數(shù)調(diào)用完畢將 返回值帶回函數(shù)調(diào)用處時。此時需要將函數(shù)中的對 象復(fù)制一個臨時對象并傳給該函數(shù)的調(diào)用處。如 Box f( ) /函數(shù) f的類型為 Box類類型 Box box1(12,15,18); return box1; /返回值是 Box類的對象 int main( ) Box box2; /定義 Box類的對象 box2 box2=f(

49、); /調(diào)用 f函數(shù),返回 Box類的臨時對象,并將它賦值給 box2 以上幾種調(diào)用復(fù)制構(gòu)造函數(shù)都是由編譯系統(tǒng)自動實(shí) 現(xiàn)的,不必由用戶自己去調(diào)用,讀者只要知道在這 些情況下需要調(diào)用復(fù)制構(gòu)造函數(shù)就可以了 。 如果有 n個同類的對象,那么每一個對象都分別有 自己的數(shù)據(jù)成員,不同對象的數(shù)據(jù)成員各自有值, 互不相干。 但是有時人們希望有某一個或幾個數(shù)據(jù) 成員為所有對象所共有。這樣可以實(shí)現(xiàn)數(shù)據(jù)共享 。 在第 7章中曾介紹過全局變量,它能夠?qū)崿F(xiàn)數(shù)據(jù)共 享。如果在一個程序文件中有多個函數(shù),在每一個 函數(shù)中都可以改變?nèi)肿兞康闹?,全局變量的值?各函數(shù)共享。但是用全局變量的安全性得不到保證, 由于在各處都可以

50、自由地修改全局變量的值,很有 可能偶一失誤,全局變量的值就被修改,導(dǎo)致程序 的失敗。因此在實(shí)際工作中很少使用全局變量。 如果想在同類的多個對象之間實(shí)現(xiàn)數(shù)據(jù)共享,也不 要用全局對象,可以用靜態(tài)的數(shù)據(jù)成員。 9.9 靜態(tài)成員 靜態(tài)數(shù)據(jù)成員是一種特殊的數(shù)據(jù)成員。 它以關(guān)鍵字 static開頭 。例如 class Box public: int volume( ); private: static int height; /把 height定義為靜態(tài)的數(shù)據(jù)成員 int width; int length; ; 如果希望各對象中的 height的值是一樣的,就可以 把它定義為靜態(tài)數(shù)據(jù)成員,這樣 它就為各

51、對象所共 有,而 不只屬于某個對象的成員 , 9.9.1 靜態(tài)數(shù)據(jù)成員 所有對象都可以引用它。每個對象都可以引用這個 靜態(tài)數(shù)據(jù)成員。靜態(tài)數(shù)據(jù)成員的值對所有對象都是 一樣的。如果改變它的值,則在各對象中這個數(shù)據(jù) 成員的值都同時改變了。這樣可以節(jié)約空間,提高 效率 。 說明: (1) 靜態(tài)數(shù)據(jù)成員不屬于某一個對象,在為對象所 分配的空間中不包括靜態(tài)數(shù)據(jù)成員所占的空間。靜 態(tài)數(shù)據(jù)成員是在所有對象之外單獨(dú)開辟空間。 只要 在類中定義了靜態(tài)數(shù)據(jù)成員,即使不定義對象,也 為靜態(tài)數(shù)據(jù)成員分配空間,它可以被引用 。 (2) 靜態(tài)數(shù)據(jù)成員 ,它不隨對象的建立而分配空間, 也不隨對象的撤銷而釋放 。 靜態(tài)數(shù)據(jù)成員

52、是在程序 編譯時被分配空間的,到程序結(jié)束時才釋放空間。 (3) 靜態(tài)數(shù)據(jù)成員可以初始化 ,但 只能在類體外進(jìn) 行初始化 。如 int Box height=10; /表示對 Box類中的數(shù)據(jù)成員初始化 其一般形式為 數(shù)據(jù)類型類名 靜態(tài)數(shù)據(jù)成員名 =初值; 不必在初始化語句中加 static。 注意: 不能用參數(shù)初始化表對靜態(tài)數(shù)據(jù)成員初始 化 。如在定義 Box類中這樣定義構(gòu)造函數(shù)是錯誤的: Box(int h,int w,int len):height(h) /錯誤, height是靜態(tài)數(shù)據(jù)成員 如果未對靜態(tài)數(shù)據(jù)成員賦初值,則編譯系統(tǒng)會自動 賦予初值 0。 (4) 靜態(tài)數(shù)據(jù)成員既可以通過對象名

53、引用,也可以 通過類名來引用。 例 9.10 引用靜態(tài)數(shù)據(jù)成員。 #include using namespace std; class Box public: Box(int,int); int volume( ); static int height; /把 height定義為公用的靜態(tài)的數(shù)據(jù)成員 int width; int length; ; Box Box(int w,int len) /通過構(gòu)造函數(shù)對 width和 length賦初值 width=w; length=len; int Box volume( ) return(height*width*length); int Bo

54、x height=10; /對靜態(tài)數(shù)據(jù)成員 height初始化 int main( ) Box a(15,20),b(20,30); couta.heightendl; /通過對象名 a引用靜態(tài)數(shù)據(jù)成員 coutb.heightendl; /通過對象名 b引用靜態(tài)數(shù)據(jù)成員 coutBox heightendl; /通過類名引用靜態(tài)數(shù)據(jù)成員 couta.volume( )endl; /調(diào)用 volume函數(shù),計(jì)算體積,輸出結(jié)果 上面 3個輸出語句的輸出結(jié)果相同 (都是 10)。所有對 象的靜態(tài)數(shù)據(jù)成員實(shí)際上是同一個數(shù)據(jù)成員。 請注意: 在上面的程序中將 height定義為公用的靜 態(tài)數(shù)據(jù)成員,所

55、以在類外可以直接引用。 在類外 可以通過對象名引用公用的靜態(tài)數(shù)據(jù)成員, 也可以通過類名引用靜態(tài)數(shù)據(jù)成員。 即使沒有定義 類對象,也可以通過類名引用靜態(tài)數(shù)據(jù)成員 。 這說明 靜態(tài)數(shù)據(jù)成員并不是屬于對象的,而是屬于 類的,但類的對象可以引用它 。 類內(nèi)可隨便訪問。 如果靜態(tài)數(shù)據(jù)成員被定義為私有的,則不能在類外 直接引用,而必須通過公用的成員函數(shù)引用 。 (5) 靜態(tài)數(shù)據(jù)成員的作用 :各對象之間的數(shù)據(jù)有了 溝通的渠道,實(shí)現(xiàn)數(shù)據(jù)共享,因此可以不使用全局 變量。 全局變量破壞了封裝的原則,不符合面向?qū)?象程序的要求 。 注意公用靜態(tài)數(shù)據(jù)成員與全局變量的不同, 靜態(tài)數(shù) 據(jù)成員的作用域只限于定義該類的作用域

56、內(nèi) 在此作 用域內(nèi),可以通過類名和域運(yùn)算符 “ ” 引用靜態(tài) 數(shù)據(jù)成員,而不論類對象是否存在。 成員函數(shù)也可以定義為靜態(tài)的,在類中聲明函數(shù)的 前面加 static就成了靜態(tài)成員函數(shù)。如 static int volume( ); 和靜態(tài)數(shù)據(jù)成員一樣, 如果要在類外調(diào)用公用的靜 態(tài)成員函數(shù),要用類名和域運(yùn)算符“ ”。 如 Box volume( ); 實(shí)際上也允許通過對象名調(diào)用靜態(tài)成員函數(shù),如 a.volume( ); 但這并不意味著此函數(shù)是屬于對象 a的, 而只是用 a 的類型而已 。 9.9.2 靜態(tài)成員函數(shù) 靜態(tài)成員函數(shù)的作用: 不是為了對象之間的溝通, 而是為了能處理靜態(tài)數(shù)據(jù)成員 。 前

57、面曾指出: 當(dāng)調(diào)用一個對象的成員函數(shù) (非靜態(tài) 成員函數(shù) )時,系統(tǒng)會把該對象的起始地址賦給成 員函數(shù)的 this指針。而靜態(tài)成員函數(shù)并不屬于某一 對象, 它與任何對象都無關(guān),因此靜態(tài)成員函數(shù)沒 有 this指針 。 既然它沒有指向某一對象,就無法對 一個對象中的非靜態(tài)成員進(jìn)行默認(rèn)訪問 。 靜態(tài)成員函數(shù)與非靜態(tài)成員函數(shù)的 根本區(qū)別 : 非靜態(tài)成員函數(shù)有 this指針,而靜態(tài)成員函數(shù)沒有 this指針。由此,靜態(tài)成員函數(shù)不能訪問本類中的 非靜態(tài)成員 。 靜態(tài)成員函數(shù)可以直接引用本類中的靜態(tài)數(shù)據(jù)成員, 靜態(tài)成員函數(shù)主要用來訪問靜態(tài)數(shù)據(jù)成員,而不訪 問非靜態(tài)成員。 假如在一個靜態(tài)成員函數(shù)中有以下 語

58、句: coutheightendl; /若 height已聲明為 static, 則引用本類中的靜態(tài)成員,合法 coutwidthendl; /若 width是非靜態(tài)數(shù)據(jù)成員,不合法 如果一定要引用本類的非靜態(tài)成員,應(yīng)該加對象名 和成員運(yùn)算符 “ .” 。如 couta.widthendl; /引用本類對象 a中的非靜態(tài)成員 假設(shè) a已定義為 Box類對象,且在當(dāng)前作用域內(nèi)有效, 則此語句合法。 例 9.11 靜態(tài)成員函數(shù)的應(yīng)用。 #include using namespace std; class Student /定義 Student類 public: Student(int n,int

59、 a,float s):num(n),age(a),score(s) /定義構(gòu)造函數(shù) void total( ); static float average( ); /聲明靜態(tài)成員函數(shù) private: int num; int age; float score; static float sum; /靜態(tài)數(shù)據(jù)成員 static int count; /靜態(tài)數(shù)據(jù)成員 ; void Student total( ) /定義非靜態(tài)成員函數(shù) sum+=score; /累加總分, 類內(nèi)訪問靜態(tài)數(shù)據(jù)成員 count+; /累計(jì)已統(tǒng)計(jì)的人數(shù), 類內(nèi)訪問靜態(tài)數(shù)據(jù)成員 float Student averag

60、e( ) /定義靜態(tài)成員函數(shù) return(sum/count); /只能訪問靜態(tài)數(shù)據(jù)成員 float Student sum=0; /對靜態(tài)數(shù)據(jù)成員初始化 int Student count=0; /對靜態(tài)數(shù)據(jù)成員初始化 int main( ) Student stud3= /定義對象數(shù)組并初始化 Student(1001,18,70), Student(1002,19,78), Student(1005,20,98) ; int n; coutn; /輸入需要求前面多少名學(xué)生的平均成績 for(int i=0;in;i+) /調(diào)用 3次 total函數(shù) studi.total( ); co

61、utthe average score of n students is Student average( )endl; /調(diào)用靜態(tài)成員函數(shù) return 0; 運(yùn)行結(jié)果為 please input the number of students:3 the average score of 3 students is 82.3333 說明: (1)在 Student類中定義了兩個靜態(tài)數(shù)據(jù)成員 sum(總 分 )和 count(累計(jì)需要統(tǒng)計(jì)的學(xué)生人數(shù) ), 這是由于 這兩個數(shù)據(jù)成員的值是需要進(jìn)行累加的, 它們并不 是只屬于某一個對象元素,而是由各對象元素共享 的,可以看出: 它們的值是在不斷變化

62、的,而且 無論對哪個對象元素而言,都是相同的,而且始終 不釋放內(nèi)存空間。 (2)注意: total是公有的成員函數(shù),公有的成員函 數(shù)可以引用本對象中的一般數(shù)據(jù)成員 (非靜態(tài)數(shù)據(jù) 成員 ),也可以引用類中的靜態(tài)數(shù)據(jù)成員。 score是 非靜態(tài)數(shù)據(jù)成員, sum和 count是靜態(tài)數(shù)據(jù)成員。 (3) average是靜態(tài)成員函數(shù),可以 直接 引用私有的 靜態(tài)數(shù)據(jù)成員 (不必加類名或?qū)ο竺?),函數(shù)返回成 績的平均值。 (4) 在 main函數(shù)中,引用 total函數(shù)要加對象名 (今用 對象數(shù)組元素名 ),引用靜態(tài)成員函數(shù) average函數(shù) 要用 類名或?qū)ο竺?。 類的基本訪問規(guī)則: 在一個類中可

63、以有公用的 (public)成員和私有的 (private)成員。在類外可以訪 問公用成員,只有本類中的函數(shù)可以訪問本類的私 有成員。 現(xiàn)在,我們來補(bǔ)充介紹一個例外 友元 (friend)。 友元可以訪問與其有好友關(guān)系的類中的私有成員。 友元包括友元函數(shù)和友元類。 9.10 友元 如果 在本類以外的其他地方定義了一個函數(shù) (這個 函數(shù)可以是不屬于任何類的非成員函數(shù),也可以是 其他類的成員函數(shù) )。 在類體中用 friend對其進(jìn)行聲明,此函數(shù)就稱為本 類的友元函數(shù)。友元函數(shù)可以訪問這個類中的私有 成員,但是 外部訪問 。 9.10.1 友元函數(shù) 1. 將普通函數(shù)聲明為友元函數(shù) 例 9.12 友

64、元函數(shù)的簡單例子。 #include using namespace std; class Time public: Time(int,int,int); friend void display(Time /聲明 display函數(shù)為 Time類的友元函數(shù) private: /以下數(shù)據(jù)是私有數(shù)據(jù)成員 int hour; int minute; int sec; ; Time Time(int h,int m,int s) /構(gòu)造函數(shù),給 hour,minute,sec賦初值 hour=h; minute=m; sec=s; void display(Time int main( ) Time

65、t1(10,13,56); display(t1); return 0; /調(diào)用 display函數(shù),實(shí)參 t1是 Time類對象 程序輸出結(jié)果如下: 10:13:56 由于聲明了 display是 Time類的 friend函數(shù),所以 display函數(shù)可以引用 Time中的私有成員 hour,minute,sec。 但注意在引用這些私有數(shù)據(jù)成員時,必須加上對象 名,不能寫成 couthour:minute:secendl; 與類的成員函數(shù)的區(qū)別! 只能以外部方式訪問私有 成員。 2. 友元成員函數(shù) friend函數(shù)不僅可以是一般函數(shù) (非成員函數(shù) ),而 且 可以是另一個類中的成員函數(shù) 。

66、 例 9.13 友元成員函數(shù)的簡單應(yīng)用。 #include using namespace std; class Date; /對 Date類的提前引用聲明,?因在 Time類中用到 class Time /定義 Time類 public: Time(int,int,int); void display(Date /display是成員函數(shù),形參是 Date類對象的引用 private: int hour; int minute; int sec; ; class Date /聲明 Date類 public: Date(int,int,int); friend void Time display(Date /聲明 Time中的 display函數(shù) 為本類的友元成 員函數(shù) private: int month; int day; int year; ; Time Time(int h,int m,int s) /類 Time的構(gòu)造函數(shù) hour=h; minute=m; sec=s; void Time display(Date /引用 Date類對象 中的私有數(shù)據(jù) couthour:m

展開閱讀全文
溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

相關(guān)資源

更多
正為您匹配相似的精品文檔
關(guān)于我們 - 網(wǎng)站聲明 - 網(wǎng)站地圖 - 資源地圖 - 友情鏈接 - 網(wǎng)站客服 - 聯(lián)系我們

copyright@ 2023-2025  zhuangpeitu.com 裝配圖網(wǎng)版權(quán)所有   聯(lián)系電話:18123376007

備案號:ICP2024067431-1 川公網(wǎng)安備51140202000466號


本站為文檔C2C交易模式,即用戶上傳的文檔直接被用戶下載,本站只是中間服務(wù)平臺,本站所有文檔下載所得的收益歸上傳人(含作者)所有。裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對上載內(nèi)容本身不做任何修改或編輯。若文檔所含內(nèi)容侵犯了您的版權(quán)或隱私,請立即通知裝配圖網(wǎng),我們立即給予刪除!