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

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

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

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

14.9 積分

下載資源

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

資源描述:

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

1、第9章 關(guān)于類(lèi)和對(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 類(lèi)模板,在建立一個(gè)對(duì)象時(shí),作某些初始化的工作如對(duì)數(shù)據(jù)成員賦初值。即在創(chuàng)建對(duì)象(分配內(nèi)存時(shí))進(jìn)行數(shù)據(jù)成員的初始化,因?yàn)閷?duì)象是實(shí)實(shí)在在的對(duì)象,不能無(wú)具體屬性值。 注意: 類(lèi)的數(shù)據(jù)成員是不能在聲明類(lèi)時(shí)初始化的。,9.1 構(gòu)造函數(shù)作用:創(chuàng)建對(duì)象(分配內(nèi)存時(shí))時(shí)進(jìn)行數(shù)據(jù)成員的初始化9.1.1 對(duì)象的初始化,如果一個(gè)類(lèi)中所有的成員都是公用的,

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

3、類(lèi)型,不返回任何值。 構(gòu)造函數(shù)的功能是由用戶(hù)定義的,用戶(hù)根據(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ù)名與類(lèi)名相同 hour=0; /利用構(gòu)造函數(shù)對(duì)對(duì)象中的數(shù)據(jù)成員賦初值 minute=0; sec=0; void set_time( ); /函數(shù)聲明 void show_time( ); /函數(shù)聲明 private: int hour; /私有數(shù)據(jù)成員 int minute; int se

4、c; ;,void Timeset_time( ) /定義成員函數(shù),向數(shù)據(jù)成員賦值 cinhour; cinminute; cinsec; void Timeshow_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ì)象t2,同時(shí)調(diào)用構(gòu)造函數(shù)t2.Time( ) t2.show_time( ); /顯示t2的數(shù)

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

6、義構(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ù),這種方式使該類(lèi)的每一個(gè)對(duì)象都得到同一組初值。 帶參數(shù)的構(gòu)造函數(shù),用戶(hù)希望對(duì)不同的對(duì)象賦予不同的初值。 構(gòu)造函數(shù)首部的一般格式: 構(gòu)造函數(shù)名(類(lèi)型 1 形參1,類(lèi)型2 形參2,) 實(shí)參是在定義對(duì)象時(shí)給出的。 定義對(duì)象的一般格式為 : 類(lèi)名 對(duì)象名(實(shí)參1,實(shí)參2,);,9.1.3 帶參數(shù)的構(gòu)造函數(shù),例9.2 有兩個(gè)長(zhǎng)方柱,其長(zhǎng)、寬、高分別為: (1)12,20,25;(2)10,14,20。求它們的體積。編一個(gè)基于對(duì)象的程序,在類(lèi)中用帶參數(shù)的構(gòu)造函數(shù)。 #include

7、 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; ; BoxBox(int h,int w,int len) /在類(lèi)外定義帶參數(shù)的構(gòu)造函數(shù) height=h; width=w; length=len; ,int Boxvolume( ) /定義計(jì)算體積的函數(shù) return(height*width*length); int main( ) Box box1(12,25

8、,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 9000 The volume of box2 is 9450 注意: 帶參數(shù)的構(gòu)造函數(shù)中的形參,其對(duì)應(yīng)的實(shí)參在定義對(duì)象時(shí)給定。,C+還提供另一種初始化數(shù)據(jù)成員的方法參數(shù)初始化表來(lái)

9、實(shí)現(xiàn)對(duì)數(shù)據(jù)成員的初始化。 這種方法不在函數(shù)體內(nèi)對(duì)數(shù)據(jù)成員初始化,而是在函數(shù)首部實(shí)現(xiàn)。例如例9.2中定義構(gòu)造函數(shù)可以改用以下形式: BoxBox(int h,int w,int len):height(h),width(w),length(len) 這種寫(xiě)法方便、簡(jiǎn)練,尤其當(dāng)需要初始化的數(shù)據(jù)成員較多時(shí)更顯其優(yōu)越性。甚至可以直接在類(lèi)體中(而不是在類(lèi)外)定義構(gòu)造函數(shù)。,9.1.4 用參數(shù)初始化表對(duì)數(shù)據(jù)成員初始化,在一個(gè)類(lèi)中可以定義多個(gè)構(gòu)造函數(shù),以便對(duì)類(lèi)對(duì)象提供不同的初始化的方法,供用戶(hù)選用。 這些構(gòu)造函數(shù)具有相同的名字,而參數(shù)的個(gè)數(shù)或參數(shù)的類(lèi)型不相同。這稱(chēng)為構(gòu)造函數(shù)的重載。 在第4章第4.6節(jié)中所介

10、紹的函數(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 len):height(h),width(w),length(len) /聲明一個(gè)有參的構(gòu)造函數(shù),用參數(shù)的初始化表對(duì)數(shù)據(jù)成員初始化 int volume( ); private: int height; int width; in

11、t length; ; BoxBox( ) /定義一個(gè)無(wú)參的構(gòu)造函數(shù) height=10; width=10; length=10; ,int Boxvolume( ) return(height*width*length); int main( ) Box box1; /建立對(duì)象box1,不指定實(shí)參 coutThe volume of box1 is box1.volume( )endl; Box box2(15,30,25); /建立對(duì)象box2,指定3個(gè)實(shí)參 coutThe volume of box2 is box2.volume( )endl; return 0; 在本程序中定義了兩

12、個(gè)重載的構(gòu)造函數(shù),其實(shí)還可以定義其他重載構(gòu)造函數(shù)。,說(shuō)明: (1) 調(diào)用構(gòu)造函數(shù)時(shí)不必給出實(shí)參的構(gòu)造函數(shù),稱(chēng)為默認(rèn)構(gòu)造函數(shù)(default constructor)。顯然,無(wú)參的構(gòu)造函數(shù)屬于默認(rèn)構(gòu)造函數(shù)。一個(gè)類(lèi)只能有一個(gè)默認(rèn)構(gòu)造函數(shù)。 (2) 如果在建立對(duì)象時(shí)選用的是無(wú)參構(gòu)造函數(shù),應(yīng)注意正確書(shū)寫(xiě)定義對(duì)象的語(yǔ)句。 (3) 盡管在一個(gè)類(lèi)中可以包含多個(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)值,即如果用戶(hù)不指定實(shí)參值,編譯系統(tǒng)就使形參取默認(rèn)值。 例9.4 將例9.3程序中的構(gòu)造函數(shù)改用含

13、默認(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ù) int volume( ); private: int height; int width; int length; ; BoxBox(int h,int w,int len) /在定義函數(shù)時(shí)可以不指定默認(rèn)參數(shù) height=h; width=w; length=len; ,int Bo

14、xvolume( ) 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 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 o

15、f box4 is box4.volume( )endl; return 0; ,析構(gòu)函數(shù)(destructor)也是一個(gè)特殊的成員函數(shù),它的作用與構(gòu)造函數(shù)相反,它的名字是類(lèi)名的前面加一個(gè)“”符號(hào)。在C+中“”是位取反運(yùn)算符,從這點(diǎn)也可以想到: 析構(gòu)函數(shù)是與構(gòu)造函數(shù)作用相反的函數(shù)。 當(dāng)對(duì)象的生命期結(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ì)象,則在程序的流

16、程離開(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ì)象,而是在撤銷(xiāo)對(duì)象占用的內(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ù)類(lèi)型,也沒(méi)有函數(shù)參數(shù)。因此它不能被重載。一個(gè)類(lèi)可以有多個(gè)構(gòu)造函數(shù),但只能有一個(gè)析構(gòu)函數(shù)。 析構(gòu)函數(shù)的作用并不僅限于釋放資源方面,它還可以輸出有關(guān)的信息。 一般情況下,

17、類(lèi)的設(shè)計(jì)者應(yīng)當(dāng)在聲明類(lèi)的同時(shí)定義析構(gòu)函數(shù),以指定如何完成“清理”的工作。 如果用戶(hù)沒(méi)有定義析構(gòu)函數(shù),C+編譯系統(tǒng)會(huì)自動(dòng)生成一個(gè)析構(gòu)函數(shù),但它只是徒有析構(gòu)函數(shù)的名稱(chēng)和形式,實(shí)際上什么操作都不進(jìn)行。想讓析構(gòu)函數(shù)完成任何工作,都必須在定義的析構(gòu)函數(shù)中指定。,例9.5 包含構(gòu)造函數(shù)和析構(gòu)函數(shù)的C+程序。 #include #include using namespace std; class Student /聲明Student類(lèi) public: student(int n,string nam,char s ) /定義構(gòu)造函數(shù) num=n; name=nam; sex=s; coutConstruc

18、tor called.endl; /輸出有關(guān)信息 Student( ) /定義析構(gòu)函數(shù) coutDestructor called.endl; /輸出有關(guān)信息 void display( ) /定義成員函數(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 s

19、tud2(10011,Zhang_fun,m); /定義對(duì)象stud2 stud2.display( ); /輸出學(xué)生2的數(shù)據(jù) return 0; ,程序運(yùn)行結(jié)果如下: Constructor 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ù)) Destruct

20、or called. (執(zhí)行stud1的析構(gòu)函數(shù)),在使用構(gòu)造函數(shù)和析構(gòu)函數(shù)時(shí),需要特別注意對(duì)它們的調(diào)用時(shí)間和調(diào)用順序。 在一般情況下,調(diào)用析構(gòu)函數(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ǔ)類(lèi)別。這些會(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ù)

21、在文件中的所有函數(shù)(包括main函數(shù))執(zhí)行之前調(diào)用。當(dāng)main函數(shù)執(zhí)行完畢或調(diào)用exit函數(shù)時(shí)(此時(shí)程序終止),調(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è)元素都是同類(lèi)的對(duì)象)。 例如一個(gè)班有50個(gè)學(xué)生,每個(gè)學(xué)生的屬性包括姓名

22、、性別、年齡、成績(jī)等。如果為每一個(gè)學(xué)生建立一個(gè)對(duì)象,需要分別取50個(gè)對(duì)象名。用程序處理很不方便。這時(shí)可以定義一個(gè)“學(xué)生類(lèi)”對(duì)象數(shù)組,每一個(gè)數(shù)組元素是一個(gè)“學(xué)生類(lèi)”對(duì)象。例如 Student stud50; /假設(shè)已聲明了Student類(lèi),定義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ù),在

23、定義對(duì)象數(shù)組時(shí)應(yīng)當(dāng)怎樣實(shí)現(xiàn)初始化呢? 在花括號(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 對(duì)

24、象數(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 Boxvolume( ) return(height*width*length); int main( ) Box a3= /定義對(duì)象數(shù)組 Box(10,12,1

25、5), /調(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,在建立對(duì)象時(shí),編譯系統(tǒng)會(huì)為

26、每一個(gè)對(duì)象分配一定的存儲(chǔ)空間,以存放其成員。對(duì)象空間的起始地址就是對(duì)象的指針??梢远x一個(gè)指針變量,用來(lái)存放對(duì)象的指針。如果有一個(gè)類(lèi): class Time public: int hour; int minute; int sec; void get_time( ); ;,9.5 對(duì)象指針 9.5.1 指向?qū)ο蟮闹羔?void Timeget_time( ) couthour pt所指向的對(duì)象中的hour成員,即t1.hour (*pt).get_time ( ) 調(diào)用pt所指向的對(duì)象中的get_time函數(shù),即t1.get_time pt-get_time ( ) 調(diào)用pt所指向的對(duì)象中的

27、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ù)類(lèi)型名 *指針變量名; 如果Time類(lèi)的數(shù)據(jù)成員hour為公用的整型數(shù)據(jù),則可以在類(lèi)外通過(guò)指向?qū)ο髷?shù)據(jù)成員的指針變量訪(fǎng)問(wèn)對(duì)象數(shù)據(jù)成員hour。 p1= /輸出t1.hour的

28、值,例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ù) ;,TimeTime(int h,int m,int s) hour=h; minute=m; sec=s; void Timeget_time( ) /定義公有成員函數(shù) coutget_time( ); /調(diào)用p2所指向?qū)ο?即t1)的get_time函數(shù) ,每個(gè)對(duì)象中的數(shù)據(jù)成員都分別占有存儲(chǔ)空間,如果

29、對(duì)同一個(gè)類(lèi)定義了n個(gè)對(duì)象,則有n組同樣大小的空間以存放n個(gè)對(duì)象中的數(shù)據(jù)成員。但是,不同對(duì)象都調(diào)用同一個(gè)函數(shù)代碼段。 那么,當(dāng)不同對(duì)象的成員函數(shù)引用數(shù)據(jù)成員時(shí),怎么能保證引用的是所指定的對(duì)象的數(shù)據(jù)成員呢?,9.5.3 this 指針,在每一個(gè)成員函數(shù)中都包含一個(gè)特殊的指針,這個(gè)指針的名字是固定的,稱(chēng)為this。 它是指向本類(lèi)對(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*le

30、ngth的值,實(shí)際上是執(zhí)行: (this-height)*(this-width)*(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 Boxvolume( ) return (height*width*length); C+把它處理為 int Boxvolume(Box *this) return(this-height * this-width * this-length);

31、即在成員函數(shù)的形參表列中增加一個(gè)this指針。在調(diào)用該成員函數(shù)時(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類(lèi)的volume函數(shù)中,下面兩種表示方法都是合法的、相互等價(jià)的。 return(height * width * length); /隱含使用this指針 return(this-height * this-width * this-le

32、ngth); /顯式使用this指針 可以用*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ū)ο骯,從而訪(fǎng)問(wèn)對(duì)象a的成員。在使用“調(diào)用對(duì)象a的成員函數(shù)f”時(shí),應(yīng)當(dāng)對(duì)它的含義有正確的理

33、解。,有時(shí)人們希望在需要用到對(duì)象時(shí)才建立對(duì)象,在不需要用該對(duì)象時(shí)就撤銷(xiāo)它,釋放它所占的內(nèi)存空間以供別的數(shù)據(jù)使用。這樣可提高內(nèi)存空間的利用率。 用new運(yùn)算符動(dòng)態(tài)建立對(duì)象,用delete運(yùn)算符撤銷(xiāo)對(duì)象。 如果已經(jīng)定義了一個(gè)Box類(lèi),可以用下面的方法動(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類(lèi)對(duì)象,同時(shí)調(diào)用該類(lèi)的構(gòu)造函數(shù),以使該對(duì)象初始化(如果已對(duì)構(gòu)造函數(shù)賦予此功能的話(huà))。但是此時(shí)用戶(hù)還無(wú)法訪(fǎng)問(wèn)這個(gè)對(duì)象,因?yàn)檫@個(gè)對(duì)象既沒(méi)有對(duì)象名,用戶(hù)也不知道它的地址。這種對(duì)象稱(chēng)為無(wú)名對(duì)象,它確實(shí)是存在的,但它沒(méi)有名字。 用new

34、運(yùn)算符動(dòng)態(tài)地分配內(nèi)存后,將返回一個(gè)指向新對(duì)象的指針的值,即所分配的內(nèi)存空間的起始地址。用戶(hù)需要定義一個(gè)指向本類(lèi)的對(duì)象的指針變量來(lái)存放該地址。如 Box *pt; /定義一個(gè)指向Box類(lèi)對(duì)象的指針變量pt pt=new Box; /在pt中存放了新建對(duì)象的起始地址,在程序中就可以通過(guò)pt訪(fǎng)問(wèn)這個(gè)新建的對(duì)象。如 coutheight; /輸出該對(duì)象的height成員 coutvolume( ); /調(diào)用該對(duì)象的volume函數(shù),計(jì)算并輸出體積 C+還允許在執(zhí)行new時(shí),對(duì)新建立的對(duì)象進(jìn)行初始化。如(調(diào)帶參數(shù)的構(gòu)造函數(shù)) Box *pt=new Box(12,15,18); 這種寫(xiě)法是把上面兩個(gè)語(yǔ)句

35、(定義指針變量和用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ò)指針訪(fǎng)問(wèn)的,它主要應(yīng)用于動(dòng)態(tài)的數(shù)據(jù)結(jié)構(gòu),如鏈表。訪(fǎng)問(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指針值。只要檢測(cè)返回值是否為0,就可判斷分配內(nèi)存是否成功。 在不再需要使用由new建立的對(duì)象時(shí),可以用delete運(yùn)算符予以釋放。如 delete pt; /釋放p

36、t指向的內(nèi)存空間,這就撤銷(xiāo)了pt指向的對(duì)象。 在執(zhí)行delete運(yùn)算符時(shí),在釋放內(nèi)存空間之前,自動(dòng)調(diào)用析構(gòu)函數(shù),完成有關(guān)善后清理工作。,如果對(duì)一個(gè)類(lèi)定義了兩個(gè)或多個(gè)對(duì)象,則這些同類(lèi)的對(duì)象之間可以互相賦值,即一個(gè)對(duì)象的值可以賦給另一個(gè)同類(lèi)的對(duì)象。對(duì)象的值是指對(duì)象中所有數(shù)據(jù)成員的值。 對(duì)象之間的賦值也是通過(guò)賦值運(yùn)算符“=”進(jìn)行的。本來(lái),賦值運(yùn)算符“=”只能用來(lái)對(duì)單個(gè)的變量賦值,現(xiàn)在被擴(kuò)展為兩個(gè)同類(lèi)對(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

37、 = 對(duì)象名2; 注意對(duì)象名1和對(duì)象名2必須屬于同一個(gè)類(lèi)。 例如 Student stud1,stud2; /定義兩個(gè)同類(lèi)的對(duì)象 stud2=stud1; /將stud1賦給stud2 通過(guò)下面的例子可以了解怎樣進(jìn)行對(duì)象的賦值。 例9.9 對(duì)象的賦值。 #include using namespace std; class Box public: Box(int=10,int=10,int=10); /聲明有默認(rèn)參數(shù)的構(gòu)造函數(shù) int volume( ); private: int height; int width;,int length; ; BoxBox(int h,int w,int

38、len) height=h; width=w; length=len; int Boxvolume( ) return(height*width*length); /返回體積 int main( ) Box box1(15,30,25),box2; /定義兩個(gè)對(duì)象box1和box2 coutThe volume of box1 is box1.volume( )endl; box2=box1; /將box1的值賦給box2 coutThe volume of box2 is box2.volume( )endl; return 0; ,運(yùn)行結(jié)果如下: The volume of box1 is

39、 11250 The volume of box2 is 11250 說(shuō)明: (1) 對(duì)象的賦值只對(duì)其中的數(shù)據(jù)成員賦值,而不對(duì)成員函數(shù)賦值。 (2) 類(lèi)的數(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ì)象快速地復(fù)制出多個(gè)完全相同的對(duì)象。如 Box box2(box1); 其作用是用已有的對(duì)象box1去克隆出一個(gè)新對(duì)象box2。 其一般形式為 類(lèi)名 對(duì)象2(對(duì)象1); 用對(duì)象1復(fù)制出對(duì)象2。,9.8.2 對(duì)象的復(fù)制,可以看到: 它與前面介紹過(guò)的定義對(duì)象方式類(lèi)似,但是

40、括號(hào)中給出的參數(shù)不是一般的變量,而是對(duì)象。在建立對(duì)象時(shí)調(diào)用一個(gè)特殊的構(gòu)造函數(shù)復(fù)制構(gòu)造函數(shù)(copy constructor)。這個(gè)函數(shù)的形式是這樣的: /The copy constructor definition. BoxBox(const Box 復(fù)制構(gòu)造函數(shù)也是構(gòu)造函數(shù),但它只有一個(gè)參數(shù),這個(gè)參數(shù)是本類(lèi)的對(duì)象(不能是其他類(lèi)的對(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í)際上也是建

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

42、制。如 Box box2=box1,box3=box2; 按box1來(lái)復(fù)制box2和box3??梢钥闯觯?這種形式與變量初始化語(yǔ)句類(lèi)似,請(qǐng)與下面定義變量的語(yǔ)句作比較: int a=4,b=a; 這種形式看起來(lái)很直觀(guān),用起來(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

43、); /定義box1 coutThe volume of box1 is box1.volume( )endl; Box 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) 在形式上 類(lèi)名(形參表列); /普通構(gòu)造函數(shù)的聲明,如Box(int h,int w,int len); 類(lèi)名(類(lèi)名 /實(shí)

44、參是對(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è)同類(lèi)的對(duì)象對(duì)它初始化,如前面介紹的那樣。 當(dāng)函數(shù)的參數(shù)為類(lèi)的對(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)的,這樣能保證形參具有和實(shí)參完全相同的值。如 void fun(Box b) /形參是類(lèi)的對(duì)象 int main( ) Box box1(12,15,18); fun(box1); /

45、實(shí)參是類(lèi)的對(duì)象,調(diào)用函數(shù)時(shí)將復(fù)制一個(gè)新對(duì)象b return 0; , 函數(shù)的返回值是類(lèi)的對(duì)象。在函數(shù)調(diào)用完畢將返回值帶回函數(shù)調(diào)用處時(shí)。此時(shí)需要將函數(shù)中的對(duì)象復(fù)制一個(gè)臨時(shí)對(duì)象并傳給該函數(shù)的調(diào)用處。如 Box f( ) /函數(shù)f的類(lèi)型為Box類(lèi)類(lèi)型 Box box1(12,15,18); return box1; /返回值是Box類(lèi)的對(duì)象 int main( ) Box box2; /定義Box類(lèi)的對(duì)象box2 box2=f( ); /調(diào)用f函數(shù),返回Box類(lèi)的臨時(shí)對(duì)象,并將它賦值給box2 以上幾種調(diào)用復(fù)制構(gòu)造函數(shù)都是由編譯系統(tǒng)自動(dòng)實(shí)現(xiàn)的,不必由用戶(hù)自己去調(diào)用,讀者只要知道在這些情況下需要調(diào)用復(fù)

46、制構(gòu)造函數(shù)就可以了。,如果有n個(gè)同類(lèi)的對(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ù)共享。但是用全局變量的安全性得不到保證,由于在各處都可以自由地修改全局變量的值,很有可能偶一失誤,全局變量的值就被修改,導(dǎo)致程序的失敗。因此在實(shí)際工作中很少使用全局變量。 如果想在同類(lèi)的多個(gè)對(duì)象之間實(shí)現(xiàn)數(shù)據(jù)共享,也不要用全局對(duì)象,可以用靜態(tài)的數(shù)據(jù)成員。,9.9

47、靜態(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ù)成員,這樣它就為各對(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í)改變了。這樣可

48、以節(jié)約空間,提高效率。 說(shuō)明: (1) 靜態(tài)數(shù)據(jù)成員不屬于某一個(gè)對(duì)象,在為對(duì)象所分配的空間中不包括靜態(tài)數(shù)據(jù)成員所占的空間。靜態(tài)數(shù)據(jù)成員是在所有對(duì)象之外單獨(dú)開(kāi)辟空間。只要在類(lèi)中定義了靜態(tài)數(shù)據(jù)成員,即使不定義對(duì)象,也為靜態(tài)數(shù)據(jù)成員分配空間,它可以被引用。,(2) 靜態(tài)數(shù)據(jù)成員,它不隨對(duì)象的建立而分配空間,也不隨對(duì)象的撤銷(xiāo)而釋放。靜態(tài)數(shù)據(jù)成員是在程序編譯時(shí)被分配空間的,到程序結(jié)束時(shí)才釋放空間。 (3) 靜態(tài)數(shù)據(jù)成員可以初始化,但只能在類(lèi)體外進(jìn)行初始化。如 int Boxheight=10; /表示對(duì)Box類(lèi)中的數(shù)據(jù)成員初始化,其一般形式為 數(shù)據(jù)類(lèi)型類(lèi)名靜態(tài)數(shù)據(jù)成員名=初值; 不必在初始化語(yǔ)句中加st

49、atic。 注意: 不能用參數(shù)初始化表對(duì)靜態(tài)數(shù)據(jù)成員初始化。如在定義Box類(lèi)中這樣定義構(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ì)象名引用,也可以通過(guò)類(lèi)名來(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ù)成

50、員 int width; int length; ; BoxBox(int w,int len) /通過(guò)構(gòu)造函數(shù)對(duì)width和length賦初值 width=w; length=len; int Boxvolume( ) return(height*width*length); int Boxheight=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ù)成員 coutBoxheightendl; /通

51、過(guò)類(lèi)名引用靜態(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ù)成員,所以在類(lèi)外可以直接引用。 在類(lèi)外可以通過(guò)對(duì)象名引用公用的靜態(tài)數(shù)據(jù)成員,也可以通過(guò)類(lèi)名引用靜態(tài)數(shù)據(jù)成員。即使沒(méi)有定義類(lèi)對(duì)象,也可以通過(guò)類(lèi)名引用靜態(tài)數(shù)據(jù)成員。,這說(shuō)明靜態(tài)數(shù)據(jù)成員并不是屬于對(duì)象的,而是屬于類(lèi)的,但類(lèi)的對(duì)象可以引用它。類(lèi)內(nèi)可隨便訪(fǎng)問(wèn)。 如果靜態(tài)數(shù)據(jù)成員被定義為私有的,則不能在類(lèi)外直接引用,而必須通過(guò)公用的成員函數(shù)引用。 (

52、5) 靜態(tài)數(shù)據(jù)成員的作用:各對(duì)象之間的數(shù)據(jù)有了溝通的渠道,實(shí)現(xiàn)數(shù)據(jù)共享,因此可以不使用全局變量。全局變量破壞了封裝的原則,不符合面向?qū)ο蟪绦虻囊蟆?注意公用靜態(tài)數(shù)據(jù)成員與全局變量的不同,靜態(tài)數(shù)據(jù)成員的作用域只限于定義該類(lèi)的作用域內(nèi)在此作用域內(nèi),可以通過(guò)類(lèi)名和域運(yùn)算符“”引用靜態(tài)數(shù)據(jù)成員,而不論類(lèi)對(duì)象是否存在。,成員函數(shù)也可以定義為靜態(tài)的,在類(lèi)中聲明函數(shù)的前面加static就成了靜態(tài)成員函數(shù)。如 static int volume( ); 和靜態(tài)數(shù)據(jù)成員一樣,如果要在類(lèi)外調(diào)用公用的靜態(tài)成員函數(shù),要用類(lèi)名和域運(yùn)算符“”。如 Boxvolume( ); 實(shí)際上也允許通過(guò)對(duì)象名調(diào)用靜態(tài)成員函數(shù),如

53、a.volume( ); 但這并不意味著此函數(shù)是屬于對(duì)象a的,而只是用a的類(lèi)型而已。,9.9.2 靜態(tài)成員函數(shù),靜態(tài)成員函數(shù)的作用:不是為了對(duì)象之間的溝通,而是為了能處理靜態(tài)數(shù)據(jù)成員。 前面曾指出: 當(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)訪(fǎng)問(wèn)。 靜態(tài)成員函數(shù)與非靜態(tài)成員函數(shù)的根本區(qū)別: 非靜態(tài)成員函數(shù)有this指針,而靜態(tài)成員函數(shù)沒(méi)有this指針。由此,靜態(tài)成員函數(shù)不能訪(fǎng)問(wèn)本類(lèi)中的非靜態(tài)成

54、員。,靜態(tài)成員函數(shù)可以直接引用本類(lèi)中的靜態(tài)數(shù)據(jù)成員,靜態(tài)成員函數(shù)主要用來(lái)訪(fǎng)問(wèn)靜態(tài)數(shù)據(jù)成員,而不訪(fǎng)問(wèn)非靜態(tài)成員。假如在一個(gè)靜態(tài)成員函數(shù)中有以下語(yǔ)句: coutheightendl; /若height已聲明為static,則引用本類(lèi)中的靜態(tài)成員,合法 coutwidthendl; /若width是非靜態(tài)數(shù)據(jù)成員,不合法 如果一定要引用本類(lèi)的非靜態(tài)成員,應(yīng)該加對(duì)象名和成員運(yùn)算符“.”。如 couta.widthendl; /引用本類(lèi)對(duì)象a中的非靜態(tài)成員 假設(shè)a已定義為Box類(lèi)對(duì)象,且在當(dāng)前作用域內(nèi)有效,則此語(yǔ)句合法。,例9.11 靜態(tài)成員函數(shù)的應(yīng)用。 #include using namespace

55、 std; class Student /定義Student類(lèi) public: Student(int n,int 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 Studenttotal( ) /定義非靜態(tài)成員函數(shù) sum+=score; /累加總分,類(lèi)內(nèi)訪(fǎng)問(wèn)靜態(tài)

56、數(shù)據(jù)成員 count+; /累計(jì)已統(tǒng)計(jì)的人數(shù),類(lèi)內(nèi)訪(fǎng)問(wèn)靜態(tài)數(shù)據(jù)成員 ,float Studentaverage( ) /定義靜態(tài)成員函數(shù) return(sum/count); /只能訪(fǎng)問(wèn)靜態(tài)數(shù)據(jù)成員 float Studentsum=0; /對(duì)靜態(tài)數(shù)據(jù)成員初始化 int Studentcount=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ī)

57、for(int i=0;in;i+) /調(diào)用3次total函數(shù) studi.total( ); coutthe average score of n students is Studentaverage( )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類(lèi)中定義了兩個(gè)靜態(tài)數(shù)據(jù)成員sum(總分)和count(累計(jì)需要統(tǒng)計(jì)的學(xué)生人數(shù)),這是由于這兩個(gè)數(shù)據(jù)成員的值是需要進(jìn)行累加的,它們并不是

58、只屬于某一個(gè)對(duì)象元素,而是由各對(duì)象元素共享的,可以看出: 它們的值是在不斷變化的,而且無(wú)論對(duì)哪個(gè)對(duì)象元素而言,都是相同的,而且始終不釋放內(nèi)存空間。,(2)注意: total是公有的成員函數(shù),公有的成員函數(shù)可以引用本對(duì)象中的一般數(shù)據(jù)成員(非靜態(tài)數(shù)據(jù)成員),也可以引用類(lèi)中的靜態(tài)數(shù)據(jù)成員。score是非靜態(tài)數(shù)據(jù)成員,sum和count是靜態(tài)數(shù)據(jù)成員。 (3) average是靜態(tài)成員函數(shù),可以直接引用私有的靜態(tài)數(shù)據(jù)成員(不必加類(lèi)名或?qū)ο竺?,函數(shù)返回成績(jī)的平均值。 (4) 在main函數(shù)中,引用total函數(shù)要加對(duì)象名(今用對(duì)象數(shù)組元素名),引用靜態(tài)成員函數(shù)average函數(shù)要用類(lèi)名或?qū)ο竺?類(lèi)的

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

60、單例子。 #include using namespace std; class Time public: Time(int,int,int); friend void display(Time ,minute=m; sec=s; void display(Time /調(diào)用display函數(shù),實(shí)參t1是Time類(lèi)對(duì)象 程序輸出結(jié)果如下: 10:13:56,由于聲明了display是Time類(lèi)的friend函數(shù),所以display函數(shù)可以引用Time中的私有成員hour,minute,sec。 但注意在引用這些私有數(shù)據(jù)成員時(shí),必須加上對(duì)象名,不能寫(xiě)成 couthour:minute:secend

61、l; 與類(lèi)的成員函數(shù)的區(qū)別!只能以外部方式訪(fǎng)問(wèn)私有成員。,2. 友元成員函數(shù) friend函數(shù)不僅可以是一般函數(shù)(非成員函數(shù)),而且可以是另一個(gè)類(lèi)中的成員函數(shù)。 例9.13 友元成員函數(shù)的簡(jiǎn)單應(yīng)用。 #include using namespace std; class Date; /對(duì)Date類(lèi)的提前引用聲明,?因在Time類(lèi)中用到 class Time /定義Time類(lèi) public: Time(int,int,int); void display(Date ,int minute; int sec; ; class Date /聲明Date類(lèi) public: Date(int,int,i

62、nt); friend void Timedisplay(Date ,void Timedisplay(Date ,運(yùn)行時(shí)輸出: 12/25/2004 (輸出Date類(lèi)對(duì)象d1中的私有數(shù)據(jù)) 10:13:56 (輸出Time類(lèi)對(duì)象t1中的私有數(shù)據(jù)) 在本例中定義了兩個(gè)類(lèi)Time和Date。程序第3行是對(duì)Date類(lèi)的聲明,因?yàn)樵诘?行和第16行中對(duì)display函數(shù)的聲明和定義中要用到類(lèi)名Date,而對(duì)Date類(lèi)的定義卻在其后面。 在一般情況下,兩個(gè)不同的類(lèi)是互不相干的。在本例中,由于在Date類(lèi)中聲明了Time類(lèi)中的display成員函數(shù)是Date類(lèi)的“朋友”,因此該函數(shù)可以引用Date類(lèi)中所有的數(shù)據(jù)。請(qǐng)注意在本程序中調(diào)用友元函數(shù)訪(fǎng)問(wèn)有關(guān)類(lèi)的私有數(shù)據(jù)方法。,不僅可以將一個(gè)函數(shù)聲明為一個(gè)類(lèi)的“朋友”,而且可以將一個(gè)類(lèi)(例如B類(lèi))聲明為另一個(gè)類(lèi)(例如A類(lèi))的“朋友”。這時(shí)B類(lèi)就是A類(lèi)的友元類(lèi)。友元類(lèi)B中的所有函數(shù)都是A類(lèi)的友元函數(shù),可以訪(fǎng)問(wèn)A類(lèi)中的所有成員。 不講!,9.10.2 友元類(lèi),本章概念總結(jié): 構(gòu)造函數(shù),析構(gòu)函數(shù); 對(duì)象指針,this指針; 復(fù)制構(gòu)造函數(shù) 靜態(tài)數(shù)據(jù)成員,靜態(tài)函數(shù)成員 友員,友員函數(shù),友員成員函數(shù) 掌握其作用與使用規(guī)則,

展開(kāi)閱讀全文
溫馨提示:
1: 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

相關(guān)資源

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

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

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


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