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

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

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

14.9 積分

下載資源

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

資源描述:

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

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

2、個(gè)類中所有的成員都是公用的,則可以在定 義對(duì)象時(shí)對(duì)數(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)來(lái)處理對(duì)象的初 始化。 構(gòu)造函數(shù)是特殊的成員函數(shù),與其他成員函數(shù)不 同, 不需要用戶來(lái)調(diào)用它,而是在建立對(duì)象時(shí)自動(dòng) 執(zhí)行 。 構(gòu)造函數(shù)的 名字必須與類名同名 ,而不能由用戶 任意命

3、名,以便編譯系統(tǒng)能識(shí)別它并把它作為構(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ù)對(duì)對(duì)象中的數(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; /建立對(duì)象 t1, 同時(shí)調(diào)用構(gòu)造函數(shù) t1.Time( ) t1.set_time( ); /對(duì) t1的數(shù)據(jù)成員賦值 t1.show_time( ); /顯示 t1的數(shù)據(jù)成員的值 Time t2; /建立對(duì)象

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

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

7、個(gè)長(zhǎng)方柱,其長(zhǎng)、寬、高分別為: (1)12,20,25; (2)10,14,20。求它們的體積。編一個(gè) 基于對(duì)象的程序,在類中用帶參數(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); /建立對(duì)象 box1, 并指定 box1長(zhǎng)、寬、高的值 coutThe volume of box1 is box1.volume( )endl; Box box2(15,30,21); /建立對(duì)象 box2, 并指定 box2長(zhǎng)、寬、高的值 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ù)中的形參, 其對(duì)應(yīng)的實(shí)參在定義 對(duì)象時(shí)給定。 C+還提供另一種初始化數(shù)據(jù)成員的方法 參數(shù) 初始化表 來(lái)實(shí)現(xiàn)對(duì)數(shù)據(jù)成員的初始化。 這種方法不在函數(shù)體內(nèi)對(duì)數(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) 這種寫(xiě)法方便、簡(jiǎn)練,尤其當(dāng)需要初始化的數(shù)據(jù)成 員較多時(shí)更顯其優(yōu)越性。 甚至可以直接在類體中 (而不是在類外 )定義構(gòu)造函數(shù)。 9.1.4 用參數(shù)初始

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

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

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

13、包含多個(gè)構(gòu)造函數(shù),但是 對(duì)于每一個(gè)對(duì)象來(lái)說(shuō), 建立對(duì)象時(shí)只執(zhí)行其中一個(gè) 構(gòu)造函數(shù) ,并非每個(gè)構(gòu)造函數(shù)都被執(zhí)行。 構(gòu)造函數(shù)中參數(shù)的值既可以通過(guò)實(shí)參傳遞,也可以 指定為某些默認(rèn)值,即 如果用戶不指定實(shí)參值,編 譯系統(tǒng)就使形參取默認(rèn)值 。 例 9.4 將例 9.3程序中的構(gòu)造函數(shù)改用含默認(rèn)值的參 數(shù),長(zhǎng)、寬、高的默認(rèn)值均為 10。 在例 9.3程序的基礎(chǔ)上改寫(xiě)如下: 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ù)時(shí)指定默認(rèn)參數(shù) i

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

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

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

17、占用的內(nèi)存之前完成一些清理工作,使這部分內(nèi) 存可以被程序分配給新對(duì)象使用 。 程序設(shè)計(jì)者事先設(shè)計(jì)好析構(gòu)函數(shù),只要對(duì)象的生命 期結(jié)束,程序就自動(dòng)執(zhí)行析構(gòu)函數(shù)來(lái)完成這些工作。 析構(gòu)函數(shù)不返回任何值,沒(méi)有函數(shù)類型,也沒(méi)有函 數(shù)參數(shù)。 因此它不能被重載 。 一個(gè)類可以有多個(gè)構(gòu) 造函數(shù),但只能有一個(gè)析構(gòu)函數(shù)。 析構(gòu)函數(shù)的作用 并不僅限于釋放資源 方面,它還 可以 輸出有關(guān)的信息 。 一般情況下,類的設(shè)計(jì)者應(yīng)當(dāng)在聲明類的同時(shí)定義 析構(gòu)函數(shù),以指定如何完成 “ 清理 ” 的工作。 如果用戶沒(méi)有定義析構(gòu)函數(shù), C+編譯系統(tǒng)會(huì)自動(dòng) 生成一個(gè)析構(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); / 建立對(duì)象 stud1 stud1.display( ); /輸出學(xué)生 1的數(shù)據(jù) Student stud2(10011,Zhang_fun,m); /定義對(duì)象 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ù)時(shí),需要特別注意對(duì)它 們的調(diào)用時(shí)間和調(diào)用順序。 在一般情況下, 調(diào)用析構(gòu)函

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

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

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

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

25、 對(duì)象數(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ù)初始化表對(duì)數(shù)據(jù)成員初始 化 int volume( ); private: int height; int width; int length; ; int Box volume( ) return(height*width*length); int main( ) Box a3= /定義對(duì)象數(shù)組 Box(10,

26、12,15), /調(diào)用構(gòu)造函數(shù) Box, 提供第 1個(gè)元素的實(shí)參 Box(15,18,20), /調(diào)用構(gòu)造函數(shù) Box, 提供第 2個(gè)元素的實(shí)參 Box(16,20,26) /調(diào)用構(gòu)造函數(shù) Box, 提供第 3個(gè)元素的實(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、建立對(duì)象時(shí),編譯系統(tǒng)會(huì)為每一個(gè)對(duì)象分配一定 的存儲(chǔ)空間,以存放其成員。 對(duì)象空間的起始地址 就是對(duì)象的指針 ??梢远x一個(gè)指針變量,用來(lái)存 放對(duì)象的指針。如果有一個(gè)類: class Time public: int hour; int minute; int sec; void get_time( ); ; 9.5 對(duì)象指針 9.5.1 指向?qū)ο蟮闹羔?void Time get_time( ) couthour:minute:sechour pt所指向的對(duì)象中的 hour成員,即 t1.hour (*pt).get_time ( ) 調(diào)用 pt所指向的對(duì)象中的 get_time函數(shù),即 t1

28、.get_time pt-get_time ( ) 調(diào)用 pt所指向的對(duì)象中的 get_time函數(shù),即 t1.get_time 對(duì)象有地址,存放對(duì)象初始地址的指針變量就是指 向?qū)ο蟮闹羔樧兞?。?duì)象中的成員也有地址,存放 對(duì)象成員地址的指針變量就是指向?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、, 則 可以在類外 通過(guò)指向?qū)ο髷?shù)據(jù)成員的指針變量訪 問(wèn)對(duì)象數(shù)據(jù)成員 hour。 p1= /將對(duì)象 t1的數(shù)據(jù)成員 hour的地址賦給 p1, p1指向 t1.hour cout*p1endl; /輸出 t1.hour的值 例 9.7 有關(guān)對(duì)象指針的使用方法。 #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類對(duì)象 t1 int *p1= /定義指向整型數(shù)據(jù)的指針變量 p1, 并使 p1指 向 t1.hour cout*p1get_time( ); /調(diào)用 p2所指向?qū)ο?(即 t1)的 get_time函數(shù) 每個(gè)對(duì)象中的數(shù)據(jù)成員都分別占有存儲(chǔ)空間,如果 對(duì)同一個(gè)類定義了 n個(gè)對(duì)象,則有 n組同樣大小的空 間以存放 n個(gè)對(duì)象中的數(shù)據(jù)成員。但是,不同對(duì)象 都調(diào)用同一個(gè)函數(shù)代碼段。

31、那么,當(dāng)不同對(duì)象的成員函數(shù)引用數(shù)據(jù)成員時(shí),怎 么能保證引用的是所指定的對(duì)象的數(shù)據(jù)成員呢? 9.5.3 this 指針 在每一個(gè)成員函數(shù)中都包含一個(gè)特殊的指針,這個(gè) 指針的名字是固定的,稱為 this。 它是指向本類對(duì)象的指針,它的值是當(dāng)前被調(diào)用的 成員函數(shù)所在的對(duì)象的起始地址 。例如,當(dāng)調(diào)用成 員函數(shù) a.volume時(shí),編譯系統(tǒng)就把對(duì)象 a的起始地 址賦給 this指針,于是在成員函數(shù)引用數(shù)據(jù)成員時(shí), 就按照 this的指向找到對(duì)象 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ì)算出長(zhǎng)方體 a的體積。 this指針是隱式使用的,它是作為參數(shù)被傳遞給成 員函數(shù)的 。本來(lái),成員函數(shù) volume的定義如下: int Box volume( ) return (height*width*length); C+把它處理為 int Box volume(Box *this) return(this-height * this-width * this-length); 即在成員函數(shù)的形參表列中增加一個(gè) this指針。在 調(diào)用該成員函數(shù)

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

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

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

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

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

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

39、同類對(duì)象之間的賦值,這是 通過(guò)對(duì) 賦值運(yùn)算符的重載 實(shí)現(xiàn)的 。實(shí)際這個(gè)過(guò)程是 通過(guò)成員復(fù)制來(lái)完成的,即將一個(gè)對(duì)象的成員值一 一復(fù)制給另一對(duì)象的對(duì)應(yīng)成員。 9.8 對(duì)象的賦值和復(fù)制 COPY 9.8.1 對(duì)象的賦值 對(duì)象名 1 = 對(duì)象名 2; 注意對(duì)象名 1和對(duì)象名 2必須屬于同一個(gè)類 。 例如 Student stud1,stud2; /定義兩個(gè)同類的對(duì)象 stud2=stud1; /將 stud1賦給 stud2 通過(guò)下面的例子可以了解怎樣進(jìn)行對(duì)象的賦值。 例 9.9 對(duì)象的賦值。 #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; /定義兩個(gè)對(duì)象 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 說(shuō)明: (1) 對(duì)象的賦值只對(duì)其中的數(shù)據(jù)成員賦值,而不對(duì) 成員函數(shù)賦值。 (2) 類的數(shù)據(jù)成員中 不能包括動(dòng)態(tài)分配的數(shù)據(jù),否 則在賦值時(shí)可能出現(xiàn)嚴(yán)重后果 。 有時(shí)需要用到多個(gè)完全相同的對(duì)象。此外,有時(shí)需 要將對(duì)象在某一瞬時(shí)的狀態(tài)保留下來(lái)。這就是對(duì)象 的復(fù)制機(jī)制。 用一個(gè)已有的對(duì)象快

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

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

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

45、量的語(yǔ)句 作比較: int a=4,b=a; 這種形式看起來(lái)很直觀,用起來(lái)很方便。 但是其作 用都是調(diào)用復(fù)制構(gòu)造函數(shù)。 請(qǐng)注意對(duì)象的復(fù)制和對(duì)象的賦值在概念上和語(yǔ)法上 的區(qū)別 。對(duì)象的賦值是對(duì)一個(gè)已經(jīng)存在的對(duì)象賦值, 因此必須先定義被賦值的對(duì)象,才能進(jìn)行賦值。而 對(duì)象的復(fù)制則是從無(wú)到有地建立一個(gè)新對(duì)象,并使 它與一個(gè)已有的對(duì)象完全相同 (包括對(duì)象的結(jié)構(gòu)和 成員的值 )。 可以對(duì)例 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來(lái)復(fù)制 box2,box3 coutThe volume of box2 is box2.volume( )endl; coutThe volume of box3 is box3.volume( )endl; 執(zhí)行完第 3行后, 3個(gè)對(duì)象的狀態(tài)完全相同。 請(qǐng)注意普通構(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) 在建立對(duì)象時(shí),實(shí)參類型不同。系統(tǒng)會(huì)根據(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í)參是對(duì)象名,調(diào)用復(fù)制構(gòu)造函數(shù) ( 3) 在什么情況下被調(diào)用 普通構(gòu)造函數(shù)在程序中建立對(duì)象時(shí)被調(diào)用。 復(fù)制構(gòu)造函數(shù)在用已有對(duì)象復(fù)制一個(gè)新對(duì)象時(shí)被調(diào) 用, 在以下 3種情況下需要克隆對(duì)象 : 程序中需要新建立一個(gè)對(duì)象,并用另一個(gè)同類 的對(duì)象對(duì)它初始化,如前面介紹的那樣。 當(dāng)函數(shù)的參數(shù)為類的對(duì)象時(shí)。在調(diào)用函數(shù)時(shí)需 要將實(shí)參對(duì)象完整地傳遞給形參,也就是需要建立 一個(gè)實(shí)參的拷貝,這就是按實(shí)參復(fù)制一個(gè)形參,系 統(tǒng)是通過(guò)調(diào)用復(fù)制構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)的,這樣能保證 形參具有和

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

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

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

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

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

53、引用,也可以 通過(guò)類名來(lái)引用。 例 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) /通過(guò)構(gòu)造函數(shù)對(duì) width和 length賦初值 width=w; length=len; int Box volume( ) return(height*width*length); int Bo

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

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

56、內(nèi) 在此作 用域內(nèi),可以通過(guò)類名和域運(yùn)算符 “ ” 引用靜態(tài) 數(shù)據(jù)成員,而不論類對(duì)象是否存在。 成員函數(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í)際上也允許通過(guò)對(duì)象名調(diào)用靜態(tài)成員函數(shù),如 a.volume( ); 但這并不意味著此函數(shù)是屬于對(duì)象 a的, 而只是用 a 的類型而已 。 9.9.2 靜態(tài)成員函數(shù) 靜態(tài)成員函數(shù)的作用: 不是為了對(duì)象之間的溝通, 而是為了能處理靜態(tài)數(shù)據(jù)成員 。 前

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

58、句: coutheightendl; /若 height已聲明為 static, 則引用本類中的靜態(tài)成員,合法 coutwidthendl; /若 width是非靜態(tài)數(shù)據(jù)成員,不合法 如果一定要引用本類的非靜態(tài)成員,應(yīng)該加對(duì)象名 和成員運(yùn)算符 “ .” 。如 couta.widthendl; /引用本類對(duì)象 a中的非靜態(tài)成員 假設(shè) a已定義為 Box類對(duì)象,且在當(dāng)前作用域內(nèi)有效, 則此語(yǔ)句合法。 例 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)訪問(wèn)靜態(tài)數(shù)據(jù)成員 count+; /累計(jì)已統(tǒng)計(jì)的人數(shù), 類內(nèi)訪問(wèn)靜態(tài)數(shù)據(jù)成員 float Student averag

60、e( ) /定義靜態(tài)成員函數(shù) return(sum/count); /只能訪問(wèn)靜態(tài)數(shù)據(jù)成員 float Student sum=0; /對(duì)靜態(tài)數(shù)據(jù)成員初始化 int Student count=0; /對(duì)靜態(tài)數(shù)據(jù)成員初始化 int main( ) Student stud3= /定義對(duì)象數(shù)組并初始化 Student(1001,18,70), Student(1002,19,78), Student(1005,20,98) ; int n; coutn; /輸入需要求前面多少名學(xué)生的平均成績(jī) 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 說(shuō)明: (1)在 Student類中定義了兩個(gè)靜態(tài)數(shù)據(jù)成員 sum(總 分 )和 count(累計(jì)需要統(tǒng)計(jì)的學(xué)生人數(shù) ), 這是由于 這兩個(gè)數(shù)據(jù)成員的值是需要進(jìn)行累加的, 它們并不 是只屬于某一個(gè)對(duì)象元素,而是由各對(duì)象元素共享 的,可以看出: 它們的值是在不斷變化

62、的,而且 無(wú)論對(duì)哪個(gè)對(duì)象元素而言,都是相同的,而且始終 不釋放內(nèi)存空間。 (2)注意: total是公有的成員函數(shù),公有的成員函 數(shù)可以引用本對(duì)象中的一般數(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ù)返回成 績(jī)的平均值。 (4) 在 main函數(shù)中,引用 total函數(shù)要加對(duì)象名 (今用 對(duì)象數(shù)組元素名 ),引用靜態(tài)成員函數(shù) average函數(shù) 要用 類名或?qū)ο竺?。 類的基本訪問(wèn)規(guī)則: 在一個(gè)類中可

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

64、元函數(shù)的簡(jiǎn)單例子。 #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類對(duì)象 程序輸出結(jié)果如下: 10:13:56 由于聲明了 display是 Time類的 friend函數(shù),所以 display函數(shù)可以引用 Time中的私有成員 hour,minute,sec。 但注意在引用這些私有數(shù)據(jù)成員時(shí),必須加上對(duì)象 名,不能寫(xiě)成 couthour:minute:secendl; 與類的成員函數(shù)的區(qū)別! 只能以外部方式訪問(wèn)私有 成員。 2. 友元成員函數(shù) friend函數(shù)不僅可以是一般函數(shù) (非成員函數(shù) ),而 且 可以是另一個(gè)類中的成員函數(shù) 。

66、 例 9.13 友元成員函數(shù)的簡(jiǎn)單應(yīng)用。 #include using namespace std; class Date; /對(duì) Date類的提前引用聲明,?因在 Time類中用到 class Time /定義 Time類 public: Time(int,int,int); void display(Date /display是成員函數(shù),形參是 Date類對(duì)象的引用 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類對(duì)象 中的私有數(shù)據(jù) couthour:m

展開(kāi)閱讀全文
溫馨提示:
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. 裝配圖網(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ì)自己和他人造成任何形式的傷害或損失。

相關(guān)資源

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

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

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


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