版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
10.1定義類與對象
10.1.1
定義類定義一個類,在本質(zhì)上是定義一個數(shù)據(jù)類型的藍圖。實際上,類并沒有定義任何數(shù)據(jù),但它定義了類的對象包括什么,以及可以在這個對象上執(zhí)行哪些操作。定義一個類,就是定義一組屬性和對這組屬性進行操作的函數(shù)。屬性稱為類的數(shù)據(jù)成員,函數(shù)稱為類的成員函數(shù)。類定義以關(guān)鍵字class開頭,后接類的名稱。類的主體被包含在一對大括號{}中。類在定義后,必須接一個分號或一個聲明列表。下一頁返回10.1定義類與對象
一般形式如下:class類名{private:私有成員;public:公有成員;protected:受保護成員;};在類定義中,所有數(shù)據(jù)和函數(shù)(或過程)都被封裝在一起。數(shù)據(jù)封裝是面向?qū)ο缶幊痰囊粋€重要特點,它防止外部函數(shù)直接訪問類的內(nèi)部成員。無論是公有成員、私有成員還是受保護成員,都既可以是數(shù)據(jù)成員,也可以是成員函數(shù)。上一頁下一頁返回10.1定義類與對象
類成員的訪問限制是通過在類主體內(nèi)部對各個區(qū)域標(biāo)記public、private、protected來指定的。關(guān)鍵字public、private、protected稱為訪問修飾符。在程序中,公有成員在類的外部是可訪問的,可以不使用任何成員函數(shù)來設(shè)置和獲取公有變量的值。私有成員變量(或函數(shù))在類的外部是不可訪問的,甚至是不可查看的。只有類和友元函數(shù)可以訪問私有成員。默認(rèn)情況下,類的所有成員都是私有的。保護成員變量(或函數(shù))與私有成員十分相似,但是,保護成員在派生類(即子類)中是可訪問的。第12章將介紹派生類和繼承的知識。本章介紹公有成員和私有成員的使用。在實際操作中,一般會在私有區(qū)域定義成員數(shù)據(jù),在公有區(qū)域定義相關(guān)的成員函數(shù),以便在類的外部也可以調(diào)用這些函數(shù)。無須被調(diào)用的成員函數(shù),一般會在私有區(qū)域定義。上一頁下一頁返回10.1定義類與對象
結(jié)構(gòu)體和類都能用于定義新的類型,格式也幾乎相同。這兩種方法的唯一區(qū)別在于:在結(jié)構(gòu)體中,沒有指明訪問屬性,所有成員都是公有的;在類的定義中,默認(rèn)情況下,所有成員都是私有的,而且可以指定訪問屬性。在例10-1中,需要定義一個二維點的數(shù)據(jù)類型藍圖,將其命名為Point。如果定義一個Point類型的對象p,則此對象p必須包含橫坐標(biāo)和縱坐標(biāo),且橫坐標(biāo)值和縱坐標(biāo)值不可改變。因此,在Point類定義時,應(yīng)指定橫坐標(biāo)x和縱坐標(biāo)y為成員數(shù)據(jù),且其訪問屬性為private。在對象p上,可以執(zhí)行哪些操作呢?題意要求計算p點與原點的距離,而距離的計算需要橫坐標(biāo)x和縱坐標(biāo)y的值,所有橫坐標(biāo)x和縱坐標(biāo)y的值應(yīng)該怎么設(shè)置呢?上一頁下一頁返回10.1定義類與對象
對此,需要至少兩項操作:一項是設(shè)置p點的坐標(biāo)值;另一項是計算p點與原點的距離。為了方便調(diào)試,可以增加輸出坐標(biāo)點、獲取橫坐標(biāo)、獲取縱坐標(biāo)的操作。這幾項操作需要在類Point中加以定義,作為類Point的成員函數(shù)。因此,將其訪問屬性設(shè)為public,使其在類的外部可以訪問。完善類的定義還包括所有成員函數(shù)的實現(xiàn)。成員函數(shù)的實現(xiàn)通常有兩種方法:一種方法是在類定義時只給出函數(shù)原型,而將函數(shù)的定義寫在類定義外;
另一種方法是將成員函數(shù)寫在類定義中。為了減少時間開銷,如果一個成員函數(shù)不包含循環(huán)等控制語句,那么C++編譯器就會自動將其作為內(nèi)置(inline)函數(shù)處理。
這種類中函數(shù)稱為內(nèi)聯(lián)函數(shù),
即在程序調(diào)用這些函數(shù)時,直接把函數(shù)代碼嵌入調(diào)用點,而不執(zhí)行函數(shù)的調(diào)用過程。對于類內(nèi)定義的內(nèi)聯(lián)函數(shù),可以省略inline;內(nèi)聯(lián)成員函數(shù)也可寫在類定義外面,直接使用保留字inline說明即可,但必須放在同一文件中,否則無法實現(xiàn)函數(shù)代碼嵌入。上一頁下一頁返回10.1定義類與對象
類的成員函數(shù)可以重載,這種函數(shù)稱為重載函數(shù)。也就是說,類中允許參數(shù)個數(shù)不同、參數(shù)類型不同的兩個以上的成員函數(shù)有相同的函數(shù)名,當(dāng)然,它們的定義(實現(xiàn))不相同。例如,例10-1可以定義多個create函數(shù),實現(xiàn)多種方式創(chuàng)建一個二維點。如果在類體中直接定義成員函數(shù),則不需要在函數(shù)名前加類名。但是,如果在類體外定義成員函數(shù),就必須在函數(shù)名外加上類名,類名和函數(shù)名之間應(yīng)添加作用限定符“∷”。例如,“floatPoint∷distance()”
為在類體外定義類成員函數(shù)的形式。在程序設(shè)計時,將類定義和成員函數(shù)的實現(xiàn)分開,可增強程序的可讀性,也能更好地實現(xiàn)類的隱藏。通常,把類定義編寫在頭文件(h文件)中,把類實現(xiàn)編寫在實現(xiàn)文件(cpp文件)中,把簡單的成員函數(shù)編寫在類定義中。本例將create函數(shù)編寫為內(nèi)聯(lián)函數(shù),將distance和print函數(shù)編寫在類的實現(xiàn)文件中。上一頁下一頁返回10.1定義類與對象
例10-1的完整代碼清單如下:(1)Point類的頭文件:上一頁下一頁返回10.1定義類與對象
上一頁下一頁返回10.1定義類與對象
上一頁下一頁返回10.1定義類與對象
(2)Point類的實現(xiàn)文件:上一頁下一頁返回10.1定義類與對象
在C++程序中,經(jīng)常會用到類。為了方便使用,C++編譯系統(tǒng)向用戶提供類庫,包含了常用的基本類。也有不少用戶將自己常用的類放在一個專門的類庫中,當(dāng)需要使用時,可直接引用,從而實現(xiàn)代碼重用。上一頁下一頁返回10.1定義類與對象
10.1.2
聲明對象當(dāng)定義了一個類,就相當(dāng)于有了一個新的類型,那么就可以聲明這種類型的變量了。在面向?qū)ο蟪绦蛟O(shè)計中,類變量稱為對象。與普通變量一樣,對象既可以直接在程序中聲明,也可以動態(tài)申請。例如,定義Point類的對象p1、p2,一個含有20個對象的Point類的對象數(shù)組p,可以直接聲明:Pointp1,p2,p[20];上一頁下一頁返回10.1定義類與對象
也可以采用動態(tài)申請:Point?p1,?p2,?p;p1=newPoint;p2=newPoint;p=newPoint[20];當(dāng)不再使用某個動態(tài)對象時,就應(yīng)將申請到的動態(tài)內(nèi)存空間釋放。例如,將對象p1、p2和數(shù)組p對應(yīng)的動態(tài)內(nèi)存空間釋放:deletep1;deletep2;delete[]p;上一頁下一頁返回10.1定義類與對象
10.1.3操作對象與結(jié)構(gòu)體變量一樣,
同類對象可以相互賦值,
對象還可以對其成員操作。
但是,
類定義對類成員使用了public、private、protected等訪問修飾符進行訪問限制。
如果類成員是public成員,則其對象可以對其訪問。數(shù)據(jù)成員的引用方式:對象名數(shù)據(jù)成員成員函數(shù)引用的方式:對象名成員函數(shù)名(實參列表)上一頁下一頁返回10.1定義類與對象
例如,Point類的成員函數(shù)create是public成員,可以用下列方式來訪問:Pointp1,?p2;p1create(3,3);p2=newPoint;p2->create(3,4);如果類成員是private成員,則其對象不能對其訪問,但類中的成員函數(shù)可以訪問本類中的私有成員。例如:Pointp;cout<<px; //出錯,沒有訪問權(quán)限上一頁下一頁返回10.1定義類與對象
成員函數(shù)還可以訪問同類對象的任何成員。
例如,
將Point類的成員函數(shù)floatdistance()改寫,求當(dāng)前點與另一個點q的距離,q點的數(shù)據(jù)成員可以被訪問。代碼如下://實現(xiàn)當(dāng)前點與另一個點q的向量坐標(biāo)值floatPoint∷distance(Point&q){returnsqrt((x-qx)?(x-qx)+(y-qy)?(y-qy));}上一頁下一頁返回10.1定義類與對象
利用Point類的定義,可以實現(xiàn)示例中所列的功能。將實現(xiàn)代碼可以寫在另一個cpp文件中,
命名為Point_maincpp,
其代碼如下:上一頁下一頁返回10.1定義類與對象
10.1.4
對象的內(nèi)存分配與this指針一個對象包括數(shù)據(jù)成員和成員函數(shù)。假如定義了三個Point對象p1、p2、p3,分別代表二維點
(1,1)、(3,4)、(-1,1)。這三個不同對象的成員數(shù)據(jù)是不同的,但所有該類對象中的成員函數(shù)的代碼是完全相同的。C++采用了一種優(yōu)化的手段,不管創(chuàng)建了多少該類的對象,都只為數(shù)據(jù)成員分配空間,成員函數(shù)在內(nèi)存中只有一個副本,且所有對象共享這個副本。三個對象的內(nèi)存分配示意如圖10-1所示。如圖10-1所示,對象的數(shù)據(jù)成員與成員函數(shù)是分開存儲的。那么,當(dāng)執(zhí)行成員函數(shù)時,如何知道該引用哪個對象的成員數(shù)據(jù)呢?上一頁下一頁返回10.1定義類與對象
例如,Point類成員函數(shù)create的定義如下:voidcreate(floata,floatb){x=a;y=b;}上一頁下一頁返回10.1定義類與對象
系統(tǒng)如何知道x、y是哪個對象的x、y呢?實際上,C++為每個成員函數(shù)都設(shè)置一個隱藏的this指針,對成員函數(shù)中數(shù)據(jù)成員的訪問是通過this指針訪問的。例如,Point類成員函數(shù)create的實際形式如下:voidcreate(Point?this,floata,floatb){this->x=a;this->y=b;}如果執(zhí)行如下語句:p1create(-1,-1);那么編譯器將把p1的內(nèi)存地址傳給形參this,成員函數(shù)通過this指針,訪問p1的數(shù)據(jù)成員x、y。上一頁返回10.2對象的構(gòu)造與析構(gòu)
10.2.1
構(gòu)造函數(shù)如果需要為某個類的對象賦初值,那么這個類的成員函數(shù)中應(yīng)該包含一個構(gòu)造函數(shù)。構(gòu)造函數(shù)由系統(tǒng)定義對象時自動調(diào)用,無須用戶顯式調(diào)用。C++規(guī)定,構(gòu)造函數(shù)的名字必須與類名相同。例如,Point類可以定義如下構(gòu)造函數(shù),其功能與成員函數(shù)create相同。Point(floata,floatb){x=a;y=b;} //初始化橫坐標(biāo)和縱坐標(biāo)當(dāng)定義一個Point類的對象p時,系統(tǒng)將自動調(diào)用Point類的構(gòu)造函數(shù),此時需要提供初始化參數(shù)。例如:Pointp(3,4);下一頁返回10.2對象的構(gòu)造與析構(gòu)
與普通變量初始化不同的是,數(shù)據(jù)成員初始化值以實參的形式傳遞,必須有小括號。關(guān)于構(gòu)造函數(shù)的幾點說明:(1)構(gòu)造函數(shù)名必須與類名相同;
系統(tǒng)若發(fā)現(xiàn)某個對象需要賦初值,
就到類中找一個和類名同名的函數(shù)執(zhí)行。(2)構(gòu)造函數(shù)沒有返回值。
構(gòu)造函數(shù)是系統(tǒng)在對象定義時自動調(diào)用的,
不需要返回值。上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
(3)每個類至少有一個構(gòu)造函數(shù)。
如果定義類時沒有定義構(gòu)造函數(shù),
編譯器就會自動生成一個構(gòu)造函數(shù)。該構(gòu)造函數(shù)沒有參數(shù),且函數(shù)體為空。例如,Point類沒有定義構(gòu)造函數(shù),編譯器就構(gòu)造一個構(gòu)造函數(shù):Point(){};定義類對象:Pointp;系統(tǒng)則調(diào)用編譯器構(gòu)造的構(gòu)造函數(shù)。但是,如果用戶定義了構(gòu)造函數(shù),編譯器就不會生成這樣一個構(gòu)造函數(shù)了。這就意味著,在定義對象時,一定要有與構(gòu)造函數(shù)形參表對應(yīng)的實參表。上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
(4)每個類可以創(chuàng)建多個構(gòu)造函數(shù),
系統(tǒng)根據(jù)實參表的不同而調(diào)用不同的構(gòu)造函數(shù)。不帶參數(shù)的構(gòu)造函數(shù)稱為默認(rèn)構(gòu)造函數(shù),一個類通常至少有一個默認(rèn)構(gòu)造函數(shù)。如果一個類支持對象賦初值,也支持對象不賦初值,那么,該類可以創(chuàng)建兩個構(gòu)造函數(shù):有參構(gòu)造函數(shù)和無參構(gòu)造函數(shù)。當(dāng)然,該類還可以構(gòu)造一個指定默認(rèn)值的構(gòu)造函數(shù)。例如,在Point類這樣設(shè)計構(gòu)造函數(shù):Point(floata=0,floatb=0){x=a;y=b;}上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
那么,如果在定義Point類對象時不指定實參,則兩個實參的默認(rèn)值為0;如果指定實參,則實參為指定的實參值。例如,定義Point類對象:Pointp1(3,4),p2;坐標(biāo)點p1的坐標(biāo)為(3,4),
而坐標(biāo)點p2的坐標(biāo)為(0,0)。上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
(5)構(gòu)造函數(shù)可以包含一個成員初始化列表。
成員初始化列表位于函數(shù)頭和函數(shù)體之間。例如,Point類包含成員初始化列表和默認(rèn)值的構(gòu)造函數(shù):Point(floata=0,floatb=0):x(a),y(b){}即在函數(shù)首部末尾加一個冒號,然后列出參數(shù)的初始化列表。上面的初始化列表表示:用形參a的值初始化數(shù)據(jù)成員x,用形參b的值初始化數(shù)據(jù)成員y。Point類后面的大括號是空的,沒有任何執(zhí)行語句。其他類的構(gòu)造函數(shù)若需要執(zhí)行其他語句,可在函數(shù)體中實現(xiàn)。采用參數(shù)初始化列表可以減少函數(shù)體的長度,使構(gòu)造函數(shù)簡練,也可以提高構(gòu)造函數(shù)的效率,使數(shù)據(jù)成員在構(gòu)造的同時完成初值的設(shè)置。上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
綜上所述,使用包含成員初始化列表和默認(rèn)值的構(gòu)造函數(shù)來重新定義Point類,其頭文件Pointh代碼如下:上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
10.2.2
復(fù)制構(gòu)造函數(shù)在定義普通變量時,除了可以用常量初始化外,還可以使用同類變量賦值。例如:intb=c;在創(chuàng)建一個對象時,也可以用一個同類的對象對其初始化。C++使用復(fù)制構(gòu)造函數(shù)來完成。復(fù)制構(gòu)造函數(shù)以一個同類的常量應(yīng)用作為形參。它的原型如下:類名(const類名&);Point類的復(fù)制構(gòu)造函數(shù)如下:Point(constPoint&p):x(px),y(py){}//復(fù)制構(gòu)造函數(shù),使用了參數(shù)初始化列表上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
其中,p為常量對象。常量對象只能初始化,不能賦值。有了復(fù)制構(gòu)造函數(shù),在定義對象時,可以如下使用:Pointp3=p;這時,系統(tǒng)會自動調(diào)用復(fù)制構(gòu)造函數(shù),將p的數(shù)據(jù)成員值賦值給p3的數(shù)據(jù)成員。每個類都有一個復(fù)制構(gòu)造函數(shù)。如果用戶定義類時,沒有定義復(fù)制構(gòu)造函數(shù),編譯器就會自動生成一個。
該函數(shù)將形參對象的數(shù)據(jù)成員值相應(yīng)地賦值給正在創(chuàng)建的對象的數(shù)據(jù)成員。這種自動構(gòu)造的復(fù)制構(gòu)造函數(shù)稱為默認(rèn)的復(fù)制構(gòu)造函數(shù)。一般情況下,默認(rèn)的復(fù)制構(gòu)造函數(shù)足以滿足復(fù)制對象的要求。當(dāng)默認(rèn)的復(fù)制構(gòu)造函數(shù)不能滿足用戶要求時,
那需要用戶設(shè)計自己的復(fù)制構(gòu)造函數(shù)。上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
10.2.3
析構(gòu)函數(shù)有些類對象在消亡前,需要執(zhí)行一些清理工作,如釋放內(nèi)存等。但是,并不是所有的類對象在消亡前都需要清理。例如,當(dāng)Point類對象p在消亡時,不需要做清理工作,其數(shù)據(jù)成員x與y隨著對象p的消亡而自動消亡。完成類對象清理工作的函數(shù)需要在類定義時構(gòu)造,這種函數(shù)稱為析構(gòu)函數(shù)。與構(gòu)造函數(shù)一樣,析構(gòu)函數(shù)也不是由用戶調(diào)用的,而是系統(tǒng),在對象生命周期結(jié)束時自動調(diào)用的。每個類都有一個析構(gòu)函數(shù)。如果用戶沒有定義析構(gòu)函數(shù),編譯器就會自動生成一個默認(rèn)的析構(gòu)函數(shù)。該函數(shù)的函數(shù)體為空。析構(gòu)函數(shù)的名字是類名前面加一個“~”符號。例如,Point類的析構(gòu)函數(shù)由編譯器自動生成,
其形式如下:~Point(){}上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
析構(gòu)函數(shù)不返回任何值,沒有函數(shù)類型,也沒有函數(shù)參數(shù)。一個類可以有多個構(gòu)造函數(shù),但只能有一個析構(gòu)函數(shù)。在下面的例10-2中,需要編寫析構(gòu)函數(shù)。該示例的構(gòu)造函數(shù)使用運算符new來申請內(nèi)存空間,那么該示例就需要編寫析構(gòu)函數(shù),使用運算符delete來完成釋放內(nèi)存的清理工作,否則會造成內(nèi)存泄漏。上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
【例10-2】用class定義一個存儲大整數(shù)的數(shù)據(jù)類型BigInt。【分析】用某種程序設(shè)計語言進行編程時,可能需要處理非常大或者運算精度要求非常高的整數(shù)(稱為大整數(shù)),這種大整數(shù)用該語言的基本數(shù)據(jù)類型無法直接表示。處理大整數(shù)的一般方法是用數(shù)組存儲大整數(shù)(即定義一個比較大的整型數(shù)組),數(shù)組元素代表大整數(shù)的一位,通過數(shù)組元素的運算來模擬大整數(shù)的運算。令A=a1a2an表示大整數(shù),
n表示大整數(shù)的位數(shù)。
面向?qū)ο缶幊痰乃枷胧菢?gòu)造類與對象。
將大整數(shù)看作對象,
抽象大整數(shù)的所有特征后定義一種大整數(shù)類型,
并將其命名為BigInt類型。該數(shù)組有兩個數(shù)據(jù)成員:一個是整型數(shù)組data,表示大整數(shù)的各位數(shù)字;另一個是整型變量length,表示大整數(shù)的長度。為了便于執(zhí)行大整數(shù)的算術(shù)運算,可將大整數(shù)的低位存儲到數(shù)組的低下標(biāo)處,
大整數(shù)的高位存儲到數(shù)組的高下標(biāo)處。
上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
例如,大整數(shù)1234567899999,存儲到數(shù)組data為上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
為了靈活應(yīng)用存儲空間,本例采用動態(tài)內(nèi)存分配。BigInt類的成員函數(shù)及其功能如下:(1)構(gòu)造函數(shù)BigInt():無參,
構(gòu)造一個空的大整數(shù)。(2)構(gòu)造函數(shù)BigInt(stringstr):有參,
由一個只包含數(shù)字的字符串構(gòu)造一個大整數(shù),其長度為字符串str的長度。該函數(shù)將大整數(shù)存儲到一塊數(shù)組空間中,存儲空間采用運算符new動態(tài)申請。(3)復(fù)制構(gòu)造函數(shù)BigInt(constBigInt&b):有參,
重新申請內(nèi)存空間并將b中數(shù)復(fù)制到當(dāng)前對象。(4)析構(gòu)函數(shù)~BigInt():無參,
使用運算符delete釋放存儲空間。(5)成員函數(shù)intlength():無參,
返回大整數(shù)的長度。(6)成員函數(shù)voidprint():無參,
從高位到低位輸出大整數(shù)。上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
BigInt頭文件的代碼如下:上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
BigInt類的實現(xiàn)代碼如下:上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
有了BigInt類的定義,就可以定義BigInt類對象測試類的使用狀況。測試代碼可以寫在另一個cpp文件中,
可將其命名為BigInt_maincpp。
其代碼如下:上一頁下一頁返回10.2對象的構(gòu)造與析構(gòu)
【練習(xí)】創(chuàng)建一個三維空間點的類Point3D,數(shù)據(jù)成員為三個維度的坐標(biāo)值,成員函數(shù)包括構(gòu)造函數(shù)、析構(gòu)函數(shù)、輸出函數(shù)以及計算當(dāng)前點與另一點的距離等。創(chuàng)建一個工程,其中包含頭文件Point3Dh、
實現(xiàn)文件Point3Dcpp,
以及測試主文件Point3D_maincpp。上一頁返回10.3const與數(shù)據(jù)保護
10.3.1
常數(shù)據(jù)成員類的數(shù)據(jù)成員可以定義為常量。常數(shù)據(jù)成員表示它在某個對象生存期內(nèi)是常量,即在對象生成時賦予常量值,
在對象生存期內(nèi),
它的值是不能改變的。
例如,
Point類對象p1(3,4)除了在構(gòu)造函數(shù)中初始化外,在整個生存期內(nèi)是不變的,那么Point類中的橫坐標(biāo)x和縱坐標(biāo)y可被定義為常數(shù)據(jù)成員。如下所示:constfloatx; //成員數(shù)據(jù),表示橫坐標(biāo)constfloaty; //成員數(shù)據(jù),表示縱坐標(biāo)常量只能初始化,不能賦值。因此,常數(shù)據(jù)成員只能在類中通過參數(shù)初始化列表完成。例如:point(floata=0,floatb=0):x(a),y(b){}下一頁返回10.3const與數(shù)據(jù)保護
不能寫成如下:point(floata=0,floatb=0){x=a;y=b;}如果有成員函數(shù)試圖改變常數(shù)據(jù)成員的值,則編譯器報錯。如果在Point類中定義二維點平移函數(shù),試圖改變數(shù)據(jù)成員的值,則編譯系統(tǒng)報錯。平移函數(shù)代碼如下:voidpmove(floata,floatb){x+=a; //當(dāng)前坐標(biāo)點平移y+=b;}上一頁下一頁返回10.3const與數(shù)據(jù)保護
10.3.2
常成員函數(shù)類的成員函數(shù)也可以定義為常成員函數(shù)。常成員函數(shù)只能引用本類的數(shù)據(jù)成員,而不能改變它們,即成員函數(shù)是安全的,不會改變數(shù)據(jù)成員的值。例如,Point類成員函數(shù)print、distance都不會改變數(shù)據(jù)成員的值,因此可以將其都定義為常成員函數(shù)。聲明常成員函數(shù)的一般格式:類型名函數(shù)名(參數(shù)表)const常成員函數(shù)的聲明需要在成員函數(shù)聲明后面加一個保留字const。下面的代碼將Point類成員函數(shù)print、distance聲明為常成員函數(shù):floatdistance()const; //計算坐標(biāo)(x,y)與原點(0,0)的距離voidprint()const; //輸出坐標(biāo)(x,y)上一頁下一頁返回10.3const與數(shù)據(jù)保護
常成員函數(shù)的定義也需要加入const。常成員函數(shù)print、distance的定義形式如下://計算坐標(biāo)(x,y)與原點(0,0)的距離floatpoint∷distance()const{returnsqrt(x?x+y?y);}//輸出坐標(biāo)(x,y)voidpoint∷print()const{cout<<'('<<x<<','<<y<<')'<<endl;}上一頁下一頁返回10.3const與數(shù)據(jù)保護
任何不修改數(shù)據(jù)成員的函數(shù),都應(yīng)該將其聲明為const類型,以提高程序的健壯性。如果常成員函數(shù)不慎修改了數(shù)據(jù)成員,編譯器將報錯,提醒用戶更改了受保護的數(shù)據(jù)。上一頁下一頁返回10.3const與數(shù)據(jù)保護
10.3.3
常對象使用常對象,可以保護其數(shù)據(jù)成員不被修改。例如,在例10-1中,定義一個點為原點,使其值不被改變,可將其定義為常對象。定義常對象的方法是在對象前面加關(guān)鍵字const。例如:constPointp0(0,0);或者Pointconstp0(0,0);常對象只能初始化,不能賦值,而且必須初始化,否則無法指定常量的值。如果程序中有試圖改變p0的語句,編譯器將報錯。上一頁下一頁返回10.3const與數(shù)據(jù)保護
10.3.4
對象的常引用在函數(shù)調(diào)用時,如果形參為對象的引用,那么可以把引用聲明為const,即常引用。常引用能保證數(shù)據(jù)安全,使傳遞的參數(shù)對象在函數(shù)調(diào)用期間不被隨意修改。例如,在例10-2中,可以為BigInt類增加一個成員函數(shù),實現(xiàn)兩個大整數(shù)的相加。代碼如下:voidadd(constBigInt&a,constBigInt&b); //兩個大整數(shù)相加,結(jié)果存儲到當(dāng)前對象其中,形參a和b稱為常引用。如果在函數(shù)調(diào)用時,a與b的數(shù)據(jù)被更改,編譯器將報錯。在面向?qū)ο缶幊淘O(shè)計中,使用常引用作為函數(shù)形參,不僅能夠?qū)崿F(xiàn)形參與實參引用同一塊內(nèi)存空間,節(jié)省存儲空間,而且能夠使數(shù)據(jù)不能被隨意修改,從而保證數(shù)據(jù)安全。上一頁下一頁返回10.3const與數(shù)據(jù)保護
BigInt類的add成員函數(shù)可如下定義:上一頁下一頁返回10.3const與數(shù)據(jù)保護
上一頁下一頁返回10.3const與數(shù)據(jù)保護
【練習(xí)】創(chuàng)建一個日期類Date,數(shù)據(jù)成員有:month、day和year(都是int類型)。成員函數(shù)有:(1)構(gòu)造函數(shù):構(gòu)造包含參數(shù)列表和默認(rèn)值的構(gòu)造函數(shù)。(2)析構(gòu)函數(shù):可以編寫空的析構(gòu)函數(shù),
也可以由系統(tǒng)自動生成。(3)成員函數(shù)intday_of_year():返回當(dāng)前日期是1年中的第幾天?(注意閏年問題)(4)成員函數(shù)intcompare_dates(Dated):如果當(dāng)前日期在日期d之前,
就返回-1;
如果當(dāng)前日期在日期d之后,就返回1;如果當(dāng)前日期與日期d相等,就返回0。思考:在此類中,哪些成員可設(shè)為常量?上一頁返回10.4類的靜態(tài)成員與數(shù)據(jù)共享
10.4.1
靜態(tài)數(shù)據(jù)成員將一些數(shù)據(jù)成員設(shè)置為靜態(tài)成員的格式如下:static類型數(shù)據(jù)成員名例如,將例10-3的存款賬戶類Account屬性accountNum和rate設(shè)置為靜態(tài)數(shù)據(jù)成員:staticintaccountNum;staticdoublerate;由于一個類的所有對象共享靜態(tài)數(shù)據(jù)成員,所以不能用構(gòu)造函數(shù)為靜態(tài)數(shù)據(jù)成員初始化,只能在類外專門對其初始化,一般在實現(xiàn)文件中進行初始化。格式如下:數(shù)據(jù)類型類名∷靜態(tài)數(shù)據(jù)成員名=初值;下一頁返回10.4類的靜態(tài)成員與數(shù)據(jù)共享
例10-3的Account類屬性accountNum和rate初始化如下:intAccount∷accountNum=0;doubleAccount∷rate=003;如果程序未對靜態(tài)數(shù)據(jù)成員賦初值,則編譯系統(tǒng)自動用0為它賦初值。靜態(tài)數(shù)據(jù)成員在對象外單獨開辟內(nèi)存空間,只要在類中定義了靜態(tài)成員,即使不定義對象,系統(tǒng)也為靜態(tài)成員分配內(nèi)存空間,可以被引用。在程序開始時,系統(tǒng)為靜態(tài)成員分配內(nèi)存空間,直到程序結(jié)束,該內(nèi)存空間才釋放。
靜態(tài)數(shù)據(jù)成員的作用域是它的類作用域(如果在一個函數(shù)內(nèi)定義類,它的靜態(tài)數(shù)據(jù)成員作用域就是這個函數(shù)),在此范圍內(nèi)可以用“類名∷靜態(tài)成員名”的形式訪問靜態(tài)數(shù)據(jù)成員。上一頁下一頁返回10.4類的靜態(tài)成員與數(shù)據(jù)共享
10.4.2
靜態(tài)成員函數(shù)C++提供靜態(tài)成員函數(shù),可用于訪問靜態(tài)數(shù)據(jù)成員。靜態(tài)成員函數(shù)不屬于某個對象而屬于類,沒有this指針。類中的非靜態(tài)成員函數(shù)可以訪問類中的所有數(shù)據(jù)成員;而靜態(tài)成員函數(shù)可以直接訪問類的靜態(tài)成員,不能直接訪問非靜態(tài)成員。靜態(tài)成員函數(shù)聲明只需要在類定義的原型前加上保留字static,靜態(tài)函數(shù)定義既可以寫在類定義中,也可以寫在類定義外。在類外定義時,無須加static。靜態(tài)成員函數(shù)可以通過類名來調(diào)用。格式如下:類名∷成員函數(shù)(實參表)上一頁下一頁返回10.4類的靜態(tài)成員與數(shù)據(jù)共享
定義靜態(tài)成員函數(shù)的主要目的是訪問靜態(tài)數(shù)據(jù)成員,
可以在所有對象創(chuàng)建之前對靜態(tài)數(shù)據(jù)成員初始化。例如,在例10-3中,Account類靜態(tài)屬性rate的初始化可以通過編寫靜態(tài)成員函數(shù)來完成,并在所有對象創(chuàng)建之前調(diào)用。代碼如下:staticvoidsetRate(doublenewRate){rate=newRate;}上一頁下一頁返回10.4類的靜態(tài)成員與數(shù)據(jù)共享
例10-3的Account類完整定義在頭文件Accounth中。代碼如下:上一頁下一頁返回10.4類的靜態(tài)成員與數(shù)據(jù)共享
上一頁下一頁返回10.4類的靜態(tài)成員與數(shù)據(jù)共享
上一頁下一頁返回10.4類的靜態(tài)成員與數(shù)據(jù)共享
編寫Account類的測試代碼如下:上一頁下一頁返回10.4類的靜態(tài)成員與數(shù)據(jù)共享
【練習(xí)】(1)為例10-1的二維空間點類Point增加一個靜態(tài)數(shù)據(jù)成員count,
用于記錄點的個數(shù),并編寫靜態(tài)成員函數(shù),以顯示點的個數(shù)。(2)在貨運系統(tǒng)中,
必須保存每件貨物的信息,
如貨物名稱、
貨物種類、
貨物質(zhì)量等。但從全局看,還需要知道貨物的總質(zhì)量。設(shè)計一個類,實現(xiàn)上述功能。上一頁下一頁返回10.4類的靜態(tài)成員與數(shù)據(jù)共享
10.4.3
靜態(tài)常量成員如果需要類的靜態(tài)成員不允許改變(即需要共享一個常量),則可以將其定義為靜態(tài)常量成員,方法是使用關(guān)鍵詞staticconst。例如,希望Account類中利率不變,則可定義為靜態(tài)常量數(shù)據(jù)成員。定義如下:staticconstdoublerate=003; //靜態(tài)常量成員靜態(tài)常量成員必須在定義時初始化,但靜態(tài)數(shù)據(jù)成員的初始化是在類外初始化的。二者有所不同。上一頁返回10.5類的對象成員———類的組合
10.5.1
聲明類的對象成員如果要在類A中聲明B類對象為A的對象成員,就需要在類A定義的預(yù)處理部分包含類B的頭文件。例10-4定義Triangle類時需要聲明三個Point類對象,那么預(yù)處理部分需要包含Point類的頭文件,即#include"Pointh"Triangle類的頭文件代碼如下:下一頁返回10.5類的對象成員———類的組合
上一頁下一頁返回10.5類的對象成員———類的組合
上述Triangle類的頭文件在聲明類的對象成員p1、p2、p3時,沒有對其進行初始化。其原因是Point類包含了無參的構(gòu)造函數(shù)或指定默認(rèn)值的構(gòu)造函數(shù),否則,編譯器將報錯。在構(gòu)造函數(shù)中,初始化對象成員與初始化普通變量不同。例10-4的Triangle類對象成員p1、p2、p3不能像普通變量那樣賦值,必須在構(gòu)造函數(shù)中實現(xiàn)對象初始化。Triangle類有兩個構(gòu)造函數(shù),一個構(gòu)造函數(shù)采用初始化列表來初始化對象成員:Triangle(Pointa,Pointb,Pointc):p1(a),p2(b),p3(c){}上一頁下一頁返回10.5類的對象成員———類的組合
另一個構(gòu)造函數(shù)采用顯式調(diào)用構(gòu)造函數(shù)來初始化對象成員://構(gòu)造函數(shù)Triangle∷Triangle(floatx1,floaty1,floatx2,floaty2,floatx3,floaty3){//顯式調(diào)用Point類構(gòu)造函數(shù)p1=Point(x1,y1);p2=Point(x2,y2);p3=Point(x3,y3);}上一頁下一頁返回10.5類的對象成員———類的組合
10.5.2
在成員函數(shù)中使用類的對象成員通常,類的對象成員被聲明為類的私有成員,從而使私有的類對象成員在類外被限制使用,
但在類的成員函數(shù)中可以自由使用。
例10-4的成員函數(shù)“voidtriLen(float&,float&,float&)”
用于計算三角形的三條邊的長度,
并且需要將三條邊的長度返回。
采用參數(shù)的引用傳遞就可以實現(xiàn)上述功能。
Point類的公有成員函數(shù)“floatdistance(Point&)const”
可以求得當(dāng)前Point對象與另一個Point對象的距離,通過調(diào)用此函數(shù),可以求得三角形的三條邊的長度。上一頁下一頁返回10.5類的對象成員———類的組合
程序的代碼如下://計算三條邊的邊長voidTriangle∷triLen(float&s1,float&s2,float&s3){s1=p1distance(p2);s2=p2distance(p3);s3=p3distance(p1);}上一頁下一頁返回10.5類的對象成員———類的組合
例10-4中求周長和求面積的成員函數(shù)的程序代碼如下:上一頁返回10.6友元
10.6.1
友元函數(shù)友元關(guān)系是被授予的而不能索取。如果函數(shù)f要成為類A的友元,那么,類A必須顯式聲明函數(shù)f是它的友元,而不是函數(shù)f自稱為類A的友元。要將函數(shù)f聲明為類A的友元,需要在類聲明中由關(guān)鍵字friend修飾聲明,
在f的函數(shù)體中能夠通過類A的對象名訪問pri-vate和protected成員。例如,在例10-2的BigInt類的定義中,可將兩個大整數(shù)相加的成員函數(shù)改變?yōu)橛言瘮?shù),在類中如下聲明://兩個大整數(shù)相加,其結(jié)果存儲到第三個大整數(shù)friendvoidadd(constBigInt&,constBigInt&,BigInt&);友元函數(shù)的聲明可以放在類的public部分,也可以放在類的private部分。但是,將所有友元的聲明放在最前或最后的位置是一種較好的程序設(shè)計風(fēng)格。下一頁返回10.6友元
友元函數(shù)是一個全局函數(shù),它的定義可以寫在類定義的外面,像普通的全局函數(shù)的定義那樣,也可以寫在類定義的里面。友元函數(shù)add可如下定義:上一頁下一頁返回10.6友元
上一頁下一頁返回10.6友元
上一頁下一頁返回10.6友元
【練習(xí)】在類Point3D中,聲明一個友元函數(shù),用于計算三維空間中兩點間的距離。上一頁下一頁返回10.6友元
10.6.2
友元類如果聲明類B為另一個類A的友元,則類B的所有成員都能訪問類A的私有成員。在類A的定義中加入下述語句,即可聲明。friendclassB;如果只是將類B的成員函數(shù)intfun(double)聲明為友元,
則可在類A的定義中加入下述語句:friendintB∷fun(double);友元關(guān)系是單向的,如果聲明B類是A類的友元,則B類的成員函數(shù)就可以訪問A類的私有數(shù)據(jù)和保護數(shù)據(jù),但A類的成員函數(shù)卻不能訪問B類的私有數(shù)據(jù)和保護數(shù)據(jù)。友元不能傳遞,即使A類是B類的友元,B類是C類的友元,也不意味著A類是C類的友元。上一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
實訓(xùn)1
分?jǐn)?shù)類假定表示分?jǐn)?shù)的Fraction類包含兩個成員———numerator和denominator(都是int類型),分別表示分子和分母。編寫相關(guān)成員函數(shù),完成下列分?jǐn)?shù)運算:(1)將分?jǐn)?shù)化為最簡形式。(2)將分?jǐn)?shù)f1和f2相加。(3)從分?jǐn)?shù)f1中減去f2。(4)將分?jǐn)?shù)f1和f2相乘。(5)將分?jǐn)?shù)f1除以分?jǐn)?shù)f2。執(zhí)行(2)~(5)運算后,
函數(shù)返回的形式必須為最簡形式。下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
1實訓(xùn)分析根據(jù)題目要求,類名為Fraction,數(shù)據(jù)成員為numerator和denominator。成員函數(shù)中除了題目要求的運算外,還需要構(gòu)造函數(shù)與析構(gòu)函數(shù)。題目要求的運算中,“把分?jǐn)?shù)化為最簡形式”為最基本運算,可輔助完成其他運算。成員函數(shù)如下:(1)構(gòu)造函數(shù)Fraction(intnum=0,intdeno=1):numerator(num),denominator(deno):分?jǐn)?shù)初始化。(2)析構(gòu)函數(shù)~Fraction(){}:析構(gòu)函數(shù)可以為空,
由系統(tǒng)自動生成。(3)成員函數(shù)reduce():把分?jǐn)?shù)化為最簡形式,
需要分子和分母除以最大公約數(shù)。上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
(4)成員函數(shù)add(constFraction&,constFraction&):兩個分?jǐn)?shù)相加,
然后調(diào)用reduce函數(shù)化簡。(5)成員函數(shù)sub(constFraction&,constFraction&):兩個分?jǐn)?shù)相減,
然后調(diào)用reduce函數(shù)化簡。(6)成員函數(shù)mul(constFraction&,constFraction&):兩個分?jǐn)?shù)相乘,
然后調(diào)用reduce函數(shù)化簡。(7)成員函數(shù)div(constFraction&,constFraction&):兩個分?jǐn)?shù)相除,
然后調(diào)用reduce函數(shù)化簡。上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
Fraction類的頭文件代碼如下:上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
Fraction類的實現(xiàn)代碼如下:上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
2實訓(xùn)練習(xí)(1)將實訓(xùn)1表示分?jǐn)?shù)加、
減、
乘、
除的成員函數(shù)改為友元函數(shù),
并編寫測試代碼,測試結(jié)果的正確性。(2)假定Complex類包含兩個成員:real和imag(都是double類型)。
編寫成員函數(shù),完成兩個復(fù)數(shù)的相加與點乘操作,并編寫成員函數(shù)輸出復(fù)數(shù)的值。上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
實訓(xùn)2
時鐘類時鐘類Time包含三個數(shù)據(jù)成員:hours、minutes、seconds(都是int類型),分別表示小時、分鐘、秒。編寫成員函數(shù),完成下列功能:(1)設(shè)置時間。(2)顯示當(dāng)前時間。(3)計算時間函數(shù),
輸入午夜開始的秒數(shù),
計算對應(yīng)的小時(0~23)、
分鐘(0~59)、秒(0~59)。上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
1實訓(xùn)分析根據(jù)題目要求,類名為Time,數(shù)據(jù)成員為int類型變量hours、minutes和seconds。成員函數(shù)如下:(1)構(gòu)造函數(shù)Time(inth=0,intm=0,ints=0):hours(h),minutes(m),seconds(s){}:時間初始化。(2)析構(gòu)函數(shù)~Time():析構(gòu)函數(shù)可以為空,
由系統(tǒng)自動生成。(3)成員函數(shù)voidsetTime(int,int,int):設(shè)置時間。(4)成員函數(shù)voidsplieTime(inttotal_seconds):計算時間,
total_seconds為午夜開始的秒數(shù),
計算對應(yīng)的小時(0~23)、
分鐘(0~59)、
秒(0~59)并存入當(dāng)前對象。(5)成員函數(shù)voidshowTime():顯示當(dāng)前時間。上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
于每個成員函數(shù)都沒有復(fù)雜的控制結(jié)構(gòu),因此都可以編寫為內(nèi)聯(lián)函數(shù),放入頭文件。類Time的頭文件Time.h代碼如下:上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
Time類的測試代碼可編寫如下:上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
2實訓(xùn)練習(xí)定義Color類,包含三個數(shù)據(jù)成員red、green、blue(都為int類型),默認(rèn)顏色為黑色。成員函數(shù)列表:(1)voidmake_color(intred,intgreen,intblue):指定顏色給當(dāng)前對象。
(2)intgetRed():返回當(dāng)前color?qū)ο蟮模颍澹涑蓡T的值。(3)intgetGreen():返回當(dāng)前color?qū)ο蟮模纾颍澹澹畛蓡T的值。(4)intgetBlue():返回當(dāng)前color?qū)ο蟮模猓欤酰宄蓡T的值。(5)boolequal_color(constColor&c):判斷當(dāng)前對象與c的對應(yīng)成員是否相等。
若相等,就返回true;否則,返回false。上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
(6)voidbrighter():將當(dāng)前color?qū)ο笳{(diào)整到一個更亮的顏色。
調(diào)整方法:如果當(dāng)前對象的所有成員都為0,則將當(dāng)前color?qū)ο蟮娜齻€成員都設(shè)置為3;如果當(dāng)前對象的三個成員值為0~3,則將當(dāng)前color?qū)ο蟮娜齻€成員都設(shè)置為3,然后除以07;如果當(dāng)前對象的三個成員值都大于3,則將當(dāng)前color?qū)ο蟮娜齻€成員除以07,但如果超過了255,則將其置為255。(7)voiddarker():將當(dāng)前color?qū)ο笳{(diào)整到一個更暗的顏色。
調(diào)整方式是將當(dāng)前對象的所有成員乘以07(結(jié)果取整)。上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
實訓(xùn)3
隨機數(shù)類很多應(yīng)用都用到了隨機數(shù)。例如,擲硬幣問題可以通過設(shè)計一個產(chǎn)生隨機數(shù)0和1的函數(shù)來模擬;石頭、剪子、布游戲問題可以通過設(shè)計一個產(chǎn)生隨機數(shù)為0~2整數(shù)的函數(shù)來模擬游戲結(jié)果;等等。設(shè)計并實現(xiàn)一個隨機數(shù)類,類名為Random,當(dāng)需要用到隨機數(shù)時,可以定義一個隨機對象r。
如果要產(chǎn)生一個a到b之間的隨機整數(shù),
則可以調(diào)用rRandomInt(a,b)。
如果要產(chǎn)生一個a到b之間的隨機浮點數(shù),
則可以調(diào)用rRandomDouble(a,b)。上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
1實訓(xùn)分析產(chǎn)生隨機數(shù)的函數(shù)有rand函數(shù)和srand函數(shù),其定義在C語言的頭文件stdlibh中,而C++語言的庫文件cstlib兼容了C語言的頭文件。因此,程序預(yù)處理可包含任一文件。rand函數(shù)的原型:intrand(void);rand函數(shù)用來產(chǎn)生隨機數(shù),
返回一個在0到RAND_MAX(32767)之間的隨機數(shù)(整數(shù))。rand函數(shù)的內(nèi)部實現(xiàn)是用線性同余法實現(xiàn)的,是偽隨機數(shù),由于周期較長,因此在一定范圍內(nèi)可以看成是隨機的。線性同余法是指用一個隨機種子根據(jù)遞推公式產(chǎn)生一系列的隨機數(shù),具體公式及推導(dǎo)過程可查閱相關(guān)資料,在此不再贅述。如果沒有設(shè)置隨機數(shù)種子,則在調(diào)用rand函數(shù)時,系統(tǒng)自動設(shè)計隨機數(shù)種子為1。上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
如果隨機種子相同,則每次產(chǎn)生的隨機數(shù)也會相同,而srand函數(shù)可設(shè)置隨機數(shù)種子。srand函數(shù)的原型:voidsrand(usignedintseed);srand函數(shù)用于設(shè)置rand函數(shù)產(chǎn)生隨機數(shù)時的隨機數(shù)種子。參數(shù)seed是整數(shù),通??梢岳茫簦椋恚?NULL)的返回值作為seed。
time(NULL)返回自紀(jì)元Epoch(1970-01-0100:00:00UTC)起經(jīng)過的時間,
以秒為單位。由題目可知,定義的隨機類名為Random,用于產(chǎn)生整型和浮點型隨機數(shù)。Random類可以不需要數(shù)據(jù)成員,但是每次定義對象時,隨機種子應(yīng)該不同,否則所有對象會產(chǎn)生相同的隨機數(shù)。隨機種子的設(shè)置應(yīng)該在對象生成時進行,所以在構(gòu)造函數(shù)中設(shè)置隨機種子即可。上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
此外,
還需要編寫成員函數(shù)RandomInt(inta,intb)和RandomDouble(doublea,doubleb)分別產(chǎn)生a和b之間的隨機數(shù)。rand函數(shù)產(chǎn)生隨機數(shù)x的區(qū)間為[0,RAND_MAX],
即[0,32767],
需要轉(zhuǎn)換到[a,b]。轉(zhuǎn)換公式: x?(b-a+1)/(RAND_MAX+1)注意:x為int型,
b-a+1為int型,
RAND_MAX+1為int型,
執(zhí)行運算后,
結(jié)果仍為整型。如果需要取得double型,將其中任一運算對象強制轉(zhuǎn)換為double型即可,系統(tǒng)將表達式隱式轉(zhuǎn)換為double型。上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
由于每個成員函數(shù)都沒有復(fù)雜的控制結(jié)構(gòu),因此可以都編寫為內(nèi)聯(lián)函數(shù)。類Random的頭文件Random.h代碼如下:上一頁下一頁返回10.7實訓(xùn)與實訓(xùn)指導(dǎo)
上一頁下一頁返回1
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 淮南市壽縣輔警招聘考試題庫 (答案+解析)
- 耳鼻咽喉科試題及答案
- 醫(yī)療機構(gòu)面試題型及答案
- 煤礦安全生產(chǎn)管理人員考試及答案
- 消防設(shè)施操作員(初級)習(xí)題(含參考答案)
- 基礎(chǔ)護理習(xí)題庫(附答案)
- 商品選品員突發(fā)故障應(yīng)對考核試卷及答案
- 成人護理學(xué)試題及答案
- 護理組感染防控考核試題及答案
- 河南黨建考試題庫及答案
- 2025-2026學(xué)年北京市西城區(qū)初二(上期)期末考試物理試卷(含答案)
- 公路工程施工安全技術(shù)與管理課件 第09講 起重吊裝
- 河南省2025年普通高等學(xué)校對口招收中等職業(yè)學(xué)校畢業(yè)生考試語文試題 答案
- 《中醫(yī)藥健康知識講座》課件
- 中國地級市及各省份-可編輯標(biāo)色地圖
- 產(chǎn)科品管圈成果匯報降低產(chǎn)后乳房脹痛發(fā)生率課件
- 急性消化道出血的急診處理
- 馬口鐵印鐵制罐工藝流程詳解課件
- 狼蒲松齡原文及翻譯
- 預(yù)應(yīng)力管樁-試樁施工方案
- GB/T 3500-1998粉末冶金術(shù)語
評論
0/150
提交評論