再論類(lèi)和對(duì)象_第1頁(yè)
再論類(lèi)和對(duì)象_第2頁(yè)
再論類(lèi)和對(duì)象_第3頁(yè)
再論類(lèi)和對(duì)象_第4頁(yè)
再論類(lèi)和對(duì)象_第5頁(yè)
已閱讀5頁(yè),還剩63頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、Object-OrientedProgramming in C+第三章 再論類(lèi)和對(duì)象第一章 C+的初步知識(shí)第二章 類(lèi)和對(duì)象第三章 再論類(lèi)和對(duì)象第四章 運(yùn)算符重載第五章 繼承與派生第六章 多態(tài)性與虛函數(shù)第七章 輸入輸出流第八章 C+工具3.1 構(gòu)造函數(shù)3.2 析構(gòu)函數(shù)3.3 調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)的順序3.4 對(duì)象數(shù)組3.5 對(duì)象指針3.6 共用數(shù)據(jù)的保護(hù)3.7 對(duì)象的動(dòng)態(tài)建立和釋放3.8 對(duì)象的賦值和復(fù)制3.9 靜態(tài)成員3.10 友元3.1 構(gòu)造函數(shù)對(duì)象的初始化和普通變量一樣,我們定義一個(gè)變量,往往同時(shí)進(jìn)行初始化:int a = 3;而聲明類(lèi)時(shí),數(shù)據(jù)成員不能進(jìn)行初始化:class time h

2、our = 0; minute = 0; second = 0;因?yàn)轭?lèi)不是實(shí)體,不占分配存儲(chǔ)空間,顯然無(wú)法容納數(shù)據(jù)。3.1 構(gòu)造函數(shù)如果一個(gè)類(lèi)的所有數(shù)據(jù)才成員都是公用的,我們可以想結(jié)構(gòu)體變量那樣,在定義對(duì)象時(shí)(而不是聲明類(lèi)時(shí))進(jìn)行初始化:class time public:hour = 0;minute = 0;second = 0;time t1 = 13,30,20;但在類(lèi)的聲明中,數(shù)據(jù)成員往往都是私有的,不能這樣初始化。就需要一個(gè)公有成員函數(shù)來(lái)完成,而且應(yīng)該是自動(dòng)調(diào)用地完成。這就是構(gòu)造函數(shù)。3.1 構(gòu)造函數(shù)構(gòu)造函數(shù)的作用C+提供了構(gòu)造函數(shù)( constructor )來(lái)處理對(duì)象的初始化。

3、構(gòu)造函數(shù)是一個(gè)由用戶(hù)定義的特殊的成員函數(shù)。與其他成員函數(shù)不同之處在于: 用戶(hù)不能調(diào)用它,而是在定義對(duì)象時(shí),有系統(tǒng)自動(dòng)調(diào)用構(gòu)造函數(shù)。 構(gòu)造函數(shù)的名字必須與類(lèi)名一致,不能是其他名字。 構(gòu)造函數(shù)不能有任何返回類(lèi)型。 用戶(hù)如果沒(méi)有定義構(gòu)造函數(shù),系統(tǒng)會(huì)自動(dòng)生成一個(gè)構(gòu)造函數(shù),只不過(guò)函數(shù)體中沒(méi)有任何語(yǔ)句。3.1 構(gòu)造函數(shù)例3.1 將前例的時(shí)間類(lèi)定義構(gòu)造函數(shù)。在構(gòu)造函數(shù)中加入輸出語(yǔ)句,看看運(yùn)行效果。class time private: int hour, minute, second;public: time ( ) /time 類(lèi)的構(gòu)造函數(shù) hour = 0; minute = 0; second = 0

4、; void setTime ( ); void showTime ( ) cout hour “:” minute “:” second endl; ;void time:setTime ( ) couthour; coutminute; coutsecond;void main ( ) time t1; / 定義time類(lèi)對(duì)象t1,調(diào)用構(gòu)造函數(shù)tume ( ) t1.setTime( ); t1.showTime ( ); time t2; / 定義time類(lèi)對(duì)象t2,調(diào)用構(gòu)造函數(shù)tume ( ) t2.setTime ( ); t2.showTime ( );3.1 構(gòu)造函數(shù)帶參數(shù)的構(gòu)造

5、函數(shù)前一個(gè)示例中,沒(méi)產(chǎn)生一個(gè)time了的對(duì)象,其初值都初始化為0。如果用戶(hù)初始化時(shí),不想將對(duì)象初值置為0而是其它值,就需要用帶參數(shù)的構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)。 聲明一個(gè)構(gòu)造函數(shù)的一般格式為:構(gòu)造函數(shù)名 ( 類(lèi)型1 形參1,類(lèi)型2 形參2,); 定義一個(gè)對(duì)象的一般格式為:類(lèi)名 對(duì)象名 ( 實(shí)參1,實(shí)參2, );下面舉例說(shuō)明用法。3.1 構(gòu)造函數(shù)例3.2 :有兩個(gè)長(zhǎng)方體,長(zhǎng)寬高分別為(1,2,3)和(4,5,6)。試編寫(xiě)一基于對(duì)象的程序,分別求他們的體積,并且要求用帶參數(shù)的構(gòu)造函數(shù)初始化他們。#include class box private: int height, width, length; pub

6、lic: box ( int h, int w, int len ) height = h; width = w; length = len; int volume ( ) return height * width * length; ;void main ( ) box box1 (1,2,3); cout “box1的體積為” box1.volume( ) endl; box box2 (4,5,6); cout “box2的體積為” box2.volume( ) endl;3.1 構(gòu)造函數(shù)用參數(shù)初始化表對(duì)數(shù)據(jù)成員初始化C+提供另一種初始化數(shù)據(jù)成員的方法:參數(shù)初始化表來(lái)實(shí)現(xiàn)對(duì)數(shù)據(jù)成員的初

7、始化。這種方法不在函數(shù)體內(nèi)初始化數(shù)據(jù)成員,而是在函數(shù)首部實(shí)現(xiàn)。例3.2 我們改寫(xiě)成如下形式:#include class box private: int height, width, length;public: box(int h,int w,int len):height(h),width(w),length(len) int volume ( ) return height * width * length; ;void main ( ) box box1 (1,2,3); cout “box1的體積為” box1.volume( ) endl; box box2 (4,5,6); c

8、out “box2的體積為”box2.volume( ) endl;3.1 構(gòu)造函數(shù)示例中的初始化表表示,用形參h的值初始化數(shù)據(jù)成員height,用w值初始化width,用len值初始化 length。這種初始化方法比較簡(jiǎn)練,可以直接在類(lèi)體中定義構(gòu)造函數(shù)。3.1 構(gòu)造函數(shù)構(gòu)造函數(shù)的重載一個(gè)類(lèi)中,可以有多個(gè)構(gòu)造函數(shù),只要他們的參數(shù)表不同。以方便同類(lèi)對(duì)象不同初始化的需要。見(jiàn)下例3.3 :#include class circle private: float radius;public: circle( ); / 聲明一個(gè)無(wú)參數(shù)構(gòu)造函數(shù) circle( float r ): radius (r)

9、/ 聲明一個(gè)帶參數(shù)構(gòu)造函數(shù) float area ( ) return radius * radius * 3.14159; ;circle:circle ( ) radius=10.0; void main ( ) circle c1 ( 1.0 ), c2; cout “c1的面積為” c1.area( ) endl; cout “c2的面積為” c2.area( ) endl;3.1 構(gòu)造函數(shù)說(shuō)明 參數(shù)表為空的構(gòu)造函數(shù)叫默認(rèn)構(gòu)造函數(shù),一個(gè)類(lèi)中只能有一個(gè)默認(rèn)函數(shù)。 定義對(duì)象時(shí),如果想用默認(rèn)構(gòu)造函數(shù)初始化它,正確的定義形式為:circle c2;而不是:circle c2 ( ); 一個(gè)類(lèi)盡

10、管定義了多個(gè)構(gòu)造函數(shù),一個(gè)對(duì)象只能用其中一個(gè)來(lái)初始化。3.1 構(gòu)造函數(shù)使用默認(rèn)參數(shù)的構(gòu)造函數(shù)構(gòu)造函數(shù)的參數(shù)既可以通過(guò)實(shí)參傳送,也可以指定為某些默認(rèn)值。當(dāng)用戶(hù)不指定實(shí)參值時(shí),編譯系統(tǒng)便將默認(rèn)值為形參值。在實(shí)際生活中,常有一些這樣的默認(rèn)值。如計(jì)數(shù)器的默認(rèn)值為0;戰(zhàn)士的性別默認(rèn)值為“男”;男性職工退休年齡默認(rèn)值為60歲等,如果實(shí)際情況不是默認(rèn)值,則由用戶(hù)另外指定。采用默認(rèn)值,可以減少用戶(hù)的輸入量。下面舉例說(shuō)明。3.1 構(gòu)造函數(shù)例3.4 試將例3.3 的構(gòu)造函數(shù)改用默認(rèn)值的參數(shù),半徑值默認(rèn)為1.0。#include class circle private: float radius;public:

11、circle( float r = 1.0 ); / 聲明構(gòu)造函數(shù)是指定默認(rèn)參數(shù)float area ( ) return radius * radius * 3.14159; ;circle:circle ( float r ) /定義函數(shù)時(shí),可不再指定默認(rèn)參數(shù) radius = r; void main ( ) circle c1 (10.0), c2; cout “c1的面積為” c1.area( ) endl; cout “c2的面積為” c2.area( ) endl;3.1 構(gòu)造函數(shù)構(gòu)造函數(shù)中使用默認(rèn)參數(shù)的好處 提供建立對(duì)象時(shí)的多種選擇,相當(dāng)于好幾個(gè)重載的構(gòu)造函數(shù)。 即使在調(diào)用構(gòu)造

12、時(shí)不提供參數(shù)也不會(huì)出錯(cuò),因?yàn)橛心J(rèn)參數(shù)值參與對(duì)象初始化。 當(dāng)每一個(gè)對(duì)象都是相同的初始值時(shí),非常方便,用戶(hù)不需要輸入數(shù)據(jù)。3.1 構(gòu)造函數(shù)默認(rèn)參數(shù)值的構(gòu)造函數(shù)使用注意 何處指定默認(rèn)參數(shù)值?構(gòu)造函數(shù)的聲明處還是定義處?應(yīng)該在構(gòu)造函數(shù)的聲明處指定默認(rèn)參數(shù)值。因?yàn)轭?lèi)的聲明在頭文件中,用戶(hù)是看得見(jiàn)的,而防在函數(shù)的定義處,用戶(hù)不一定看得見(jiàn)。 一個(gè)類(lèi)定義了全部是默認(rèn)參數(shù)的構(gòu)造函數(shù)后,不能再定義重載的構(gòu)造函數(shù)。否則會(huì)產(chǎn)生多義性,系統(tǒng)不知道調(diào)用哪一個(gè)。例如一個(gè)類(lèi)有右邊形式 的三個(gè)重載構(gòu)造函數(shù),若定義了如 下對(duì)象: circle circle1( );它調(diào)用哪一個(gè)構(gòu)造函數(shù)呢?系統(tǒng)不 能確定,從而引起混亂。circ

13、le ( float r=2.3 );circle ( );circle ( float );3.2 析構(gòu)函數(shù)什么是析構(gòu)函數(shù)?析構(gòu)函數(shù)( destructor ) 也是一個(gè)特殊函數(shù),它的作用與構(gòu)造函數(shù)相反,是在撤消對(duì)象占用的內(nèi)存前進(jìn)行一些清理工作。它還可以被用來(lái)執(zhí)行“用戶(hù)希望在最后依次使用對(duì)象之后所執(zhí)行的任何操作”。析構(gòu)函數(shù)的名稱(chēng)是類(lèi)名的前面加一個(gè)取反符號(hào)“”。我們?cè)陬?lèi)的聲明中定義析構(gòu)函數(shù)。如果用戶(hù)不定義析構(gòu)函數(shù),系統(tǒng)便自動(dòng)生成一個(gè)空的析構(gòu)函數(shù)。析構(gòu)函數(shù)特點(diǎn): 沒(méi)有返回類(lèi)型; 沒(méi)有函數(shù)參數(shù); 不能被重載。3.2 析構(gòu)函數(shù)什么時(shí)候運(yùn)行析構(gòu)函數(shù)?當(dāng)對(duì)象的生命結(jié)束時(shí),會(huì)自動(dòng)執(zhí)行它的析構(gòu)函數(shù)。具體而言

14、,當(dāng)出現(xiàn)以下幾種情況,析構(gòu)函數(shù)就會(huì)被執(zhí)行。 如果在函數(shù)中定義了一個(gè)對(duì)象,當(dāng)函數(shù)調(diào)用結(jié)束時(shí),釋放對(duì)象,釋放對(duì)象前自動(dòng)執(zhí)行析構(gòu)函數(shù)。 static 局部對(duì)象在函數(shù)調(diào)用結(jié)束時(shí),包含的對(duì)象不會(huì)被釋放,只在main函數(shù)結(jié)束或調(diào)用exit函數(shù)時(shí),才調(diào)用static局部對(duì)象的析構(gòu)函數(shù)。 如果定義了一個(gè)全局對(duì)象,則在程序的流程離開(kāi)其作用域時(shí)(如main函數(shù)結(jié)束,或exit語(yǔ)句),調(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ù)。3.2 析構(gòu)函數(shù)#include class box private: int height, wid

15、th, length; public: box ( int h, int w, int len ) height = h; width = w; length = len; box ( ) / 析構(gòu)函數(shù) cout “Destructing a object” endl; int volume ( ) return height * width * length; ;void main ( ) box box1 (1,2,3); cout “box1的體積為” box1.volume( ) endl; box box2 (4,5,6); cout “box2的體積為” box2.volume(

16、) endl;例3.5 析構(gòu)函數(shù)舉例。3.3 調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)的順序調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)的順序先構(gòu)造的后析構(gòu),后構(gòu)造的先析構(gòu)。#include class box private: int height, width, length; public: box ( int h, int w, int len ) height = h; width = w; length = len; cout “Constructor a object” endl; box ( ) / 析構(gòu)函數(shù) cout “Destructoring a object” endl; int vol ( ) return

17、 height * width * length; ;void fn ( ) box b1( 2,2,2 ); cout“b1=”b1.vol( ) endl; static box b2( 3,3,3 ); / fn結(jié)束不析構(gòu)b2,直到main結(jié)束 cout“b2=”b2.vol( ) endl;void main ( ) fn( ); box b3 (1,2,3); cout“b3=”b3.vol( ) endl; box b4 (4,5,6); cout “b4=”b4.vol( )endl;3.4 對(duì)象數(shù)組數(shù)組不僅可以由簡(jiǎn)單變量組成,也可以由對(duì)象組成,即每一個(gè)數(shù)組元素都是同類(lèi)的對(duì)象。例

18、如,一個(gè)班有30人,每個(gè)學(xué)生的屬性包括學(xué)號(hào)、姓名、性別。我們建立起學(xué)生類(lèi)后,為每個(gè)學(xué)生建立一個(gè)對(duì)象,需要分別取30個(gè)對(duì)象名,很不方便。較好的做法是,定義一個(gè)“學(xué)生類(lèi)”,的對(duì)象數(shù)組,每一個(gè)數(shù)組元素是一個(gè)“學(xué)生類(lèi)”的對(duì)象。請(qǐng)看下面示例程序。3.4 對(duì)象數(shù)組#include #include class studengprivate: int num; char name10; char sex; public: student( int n, string nam, char s ) num = n; strcpy (name,nam); sex = s; cout “Constructor ca

19、lled.“ endl; student ( ) cout “Destructor called.” endl; void display ( );void student:display ( )cout“num:”numendl; cout“name:”nameendl; cout“sex:”; if (sex=0) cout“男”endl; else cout“女”endl;void main( )student stud3 = student(1001,“張三,1), student(1002,“李四,0), student(1003,“王五,0) ;/用指定參數(shù)的構(gòu)造函數(shù)初始化數(shù)組 c

20、out “第一個(gè)學(xué)生 ; stud0.display( ); cout “第二個(gè)學(xué)生 ; stud1.display( ); cout hour, pt-put( )class Timepublic: int hour, minute, sec; void put ( ) hour = 12; minute = 0; sec = 0; ;void main ( )Time *pt, t1; pt = &t1; pt.put ( ); cout hour“:”minute “:”secendl; cout (*pt).hour“:”(*pt).minute “:”(*pt).secendl;3.

21、5 對(duì)象指針指向?qū)ο髷?shù)據(jù)成員的指針定義一個(gè)指向?qū)ο髷?shù)據(jù)成員的指針變量的方法和前面介紹的定義指向普通變量的指針變量方法相同。定義格式:數(shù)據(jù)類(lèi)型名 * 指針變量名;例如:int *pl; / 定義指向整形數(shù)據(jù)的指針變量pl=&t1.hour; / 將t1的數(shù)據(jù)成員hour地址賦給指針pl,使其指向t1.hourcout *pl endl; / 輸出t1.hour的值3.5 對(duì)象指針指向?qū)ο蟪蓡T函數(shù)的指針定義指向?qū)ο蟪蓡T函數(shù)的指針變量的方法和定義指向普通函數(shù)的指針變量的方法有所不同。 指向普通函數(shù)的指針變量的定義方法:返回?cái)?shù)據(jù)類(lèi)型 (*指針變量名) (參數(shù)表列);例:void (*p) ( ); /

22、 p是指向void 類(lèi)型函數(shù)的指針變量 p = fun; / 將fun函數(shù)的入口地址賦給指針變量p (*p)( ); / 調(diào)用fun函數(shù)而定義一個(gè)指向?qū)ο蟪蓡T函數(shù)的指針變量則不能這樣:p = t1.put; / 出現(xiàn)編譯錯(cuò)誤,不知道t1.put所屬的類(lèi)3.5 對(duì)象指針定義指向公用成員函數(shù)的指針變量方法:返回?cái)?shù)據(jù)類(lèi)型 ( 類(lèi)名: *指針變量名) (參數(shù)表列);例:void (Time:*p2)( ); / Time:*p2的括號(hào)必須加上令指針變量指向一個(gè)公用成員函數(shù)的方法:指針變量名 = & 類(lèi)名:成員函數(shù)名;例:p2 = & Time:put;3.5 對(duì)象指針#include class Ti

23、mepublic: int hour, minute, sec; Time ( int h, int m, int s ) hour = h; minute = m; sec = s; void get_Time( ) cout hour“:” minute“:” secendl; ;void main ( )Time t1( 10,12,56 ); int *pl = &t1.hour; / 定義指向整形數(shù)據(jù)的指針,指向t1.hour cout *p1 get_Time( ); /調(diào)用p2所指對(duì)象的成員函數(shù) void (Time:*p3)( ); / 定義指向Time類(lèi)公用成員函數(shù)的指針變量

24、p3 p3 = &Time:get_Time; / 使p3指向Time類(lèi)公用成員函數(shù)get_Time( ) (t1.*p3) ( ); /調(diào)用p3所指的成員函數(shù)t1.get)Time( )3.5 對(duì)象指針this 指針通過(guò)第二章的學(xué)習(xí)我們知道,多個(gè)同類(lèi)對(duì)象在內(nèi)存中是共享成員函數(shù)的,以節(jié)省內(nèi)存空間。那么,不同對(duì)象的成員函數(shù)引用數(shù)據(jù)成員時(shí),怎么找到自己的數(shù)據(jù)成員呢?C+在每一個(gè)成員函數(shù)中都包含一個(gè)特殊的指針,這個(gè)指針的名字是固定的,成為“this”。它是指向本對(duì)象的指針,它的值是當(dāng)前被調(diào)用的成員函數(shù)所在對(duì)象的起始地址。例如,當(dāng)a的成員函數(shù)調(diào)用數(shù)據(jù)成員a.volume時(shí),編譯系統(tǒng)就把對(duì)象a的起始地址

25、賦給 this 指針,于是在成員函數(shù)引用數(shù)據(jù)成員時(shí),就按照 this 的指向找到對(duì)象a 的數(shù)據(jù)成員。3.5 對(duì)象指針比如下列涉及數(shù)據(jù)成員的運(yùn)算的返回語(yǔ)句: return length*width*height ;實(shí)際上C+處理為: return ( this -length)*(this-width)*(this-height);也可以寫(xiě)成如下形式: return (*this).length*(*this).width*(*this).height);但不能寫(xiě)成: return (*this.length) *(*this.width)*(*this.height); /錯(cuò)誤因?yàn)椤?”操作符

26、的優(yōu)先級(jí)高于指針運(yùn)算符“*”,(*this.length)就相當(dāng)于*(this.length),而 this.length 是不合法的,編譯出錯(cuò)(應(yīng)該是this-length)。3.6 共用數(shù)據(jù)的保護(hù)C+采用了不少的數(shù)據(jù)保護(hù)措施。最常用的,是將數(shù)據(jù)成員設(shè)置成私有數(shù)據(jù)( private ),以增加數(shù)據(jù)的安全性和私密性。但是,有時(shí)候要求數(shù)據(jù)在能共享的前提下能不能被篡改,我們就需要借助其他手段了。什么手段呢?可以采用const,即把要保護(hù)的數(shù)據(jù)定義為常量。3.6 共用數(shù)據(jù)的保護(hù)常對(duì)象在定義對(duì)象時(shí)指定對(duì)象為常對(duì)象。常對(duì)象中的數(shù)據(jù)成員為常變量,并且必須要有初值:Time const t1(12,34,5

27、6);這樣,在所有的場(chǎng)合中,對(duì)象t1的所有數(shù)據(jù)成員都被保護(hù)了,不能被修改。因此,凡是希望數(shù)據(jù)成員不能被改變的對(duì)象,可以聲明為常對(duì)象。其聲明格式為:類(lèi)名const 對(duì)象名(參數(shù)表列);或者:const 類(lèi)名對(duì)象名(參數(shù)表列);兩者等價(jià)。3.6 共用數(shù)據(jù)的保護(hù)如果一個(gè)對(duì)象被定義成常對(duì)象,那么不能該對(duì)象的非const 型成員函數(shù),當(dāng)然,系統(tǒng)隱含調(diào)用的構(gòu)造函數(shù)和析構(gòu)函數(shù)除外。比如:Time const t1( 12,34,56); / 定義t1為常對(duì)象t1.get_Time( ); / 錯(cuò)誤,get_Tiem( )不是const 型,不能調(diào)用為什么會(huì)這樣?因?yàn)槌蓡T函數(shù)有可能修改數(shù)據(jù)成員,而成員函數(shù)的定

28、義可能和成員函數(shù)的聲明不在同一文件,系統(tǒng)沒(méi)法檢測(cè)。所以,系統(tǒng)只能統(tǒng)一攔截,不讓用戶(hù)調(diào)用常對(duì)象的成員函數(shù),除非該成員函數(shù)被聲明成 const 類(lèi)型。3.6 共用數(shù)據(jù)的保護(hù)怎樣才能引用常對(duì)象的成員函數(shù)呢?很簡(jiǎn)單,只需要把該成員函數(shù)的聲明為 const 類(lèi)型,即常成員函數(shù)就行了。方法為:函數(shù)返回類(lèi)型函數(shù)名(參數(shù)表列)const;比如:void get_Time( ) const; / 將函數(shù)聲明成const 類(lèi)型常成員函數(shù)可以訪(fǎng)問(wèn)常對(duì)象中的數(shù)據(jù)成員,但仍然不準(zhǔn)修改它們。有時(shí)候編程要求必須修改某個(gè)常對(duì)象中的數(shù)據(jù)成員,如某個(gè)計(jì)數(shù)器count ,ANSI C+對(duì)此做了特殊的處理,將該數(shù)據(jù)成員 聲明為 mu

29、stable,如:mustable int count;這樣,常對(duì)象的數(shù)據(jù)成員count,就可以用常成員函數(shù)來(lái)訪(fǎng)問(wèn)和修改了。3.6 共用數(shù)據(jù)的保護(hù)常對(duì)象成員 常數(shù)據(jù)成員:其作用和用法與一般常變量相似,在類(lèi)的聲明中,用關(guān)鍵詞 const 來(lái)聲明常數(shù)據(jù)成員,例如:const int hour;注意:常數(shù)據(jù)成員的初始化,不能采用在構(gòu)造函數(shù)中對(duì)常數(shù)據(jù)成員賦予初值的方法,只能通過(guò)構(gòu)造函數(shù)的參數(shù)初始化表對(duì)常數(shù)據(jù)成員進(jìn)行初始化。在類(lèi)外定義構(gòu)造函數(shù),初始化形式為:Time:Time ( int h ): hour ( h ) 在類(lèi)中聲明了某一個(gè)數(shù)據(jù)成員為常數(shù)據(jù)成員后,該類(lèi)的所有對(duì)象中的該數(shù)據(jù)成員的值是不可改變

30、的,但可以是不同的(由每個(gè)對(duì)象的參數(shù)初始化表決定)。3.6 共用數(shù)據(jù)的保護(hù) 常成員函數(shù)一般的成員函數(shù)可以引用本對(duì)象中的非const 數(shù)據(jù)成員,也可以修改它們。但如果成員函數(shù)聲明為常成員函數(shù),則只能引用本對(duì)象中的數(shù)據(jù)成員,而不能修改它們。如void get_Time( ) const; / const位置在最后const 是函數(shù)類(lèi)型的一部分,在聲明函數(shù)和定義函數(shù)時(shí)都要用到 const 關(guān)鍵字。常成員函數(shù)可以引用常數(shù)據(jù)成員,也可以引用非const數(shù)據(jù)成員;而常數(shù)據(jù)成員可以被常成員函數(shù)引用,也可以被非 const 成員函數(shù)引用。夠亂的,見(jiàn)90頁(yè)表總結(jié)。3.6 共用數(shù)據(jù)的保護(hù)數(shù)據(jù)成員非const成員函

31、數(shù)const 成員函數(shù)非const 數(shù)據(jù)成員可引用,可修改可引用,不可修改const 數(shù)據(jù)成員可引用,不可修改可引用,不可修改常對(duì)象的數(shù)據(jù)成員不可引用,不可修改可引用,不可修改3.6 共用數(shù)據(jù)的保護(hù)怎樣使用常成員函數(shù)呢?類(lèi)中如果一些數(shù)據(jù)成員需要保護(hù),另一些數(shù)據(jù)成員不需保護(hù),我們就將需要保護(hù)的數(shù)據(jù)成員聲明為 const ,以保證其值不被改變。類(lèi)中如果所有數(shù)據(jù)成員都需保護(hù),可以將所有數(shù)據(jù)成員都聲明成 const ,本對(duì)象的任何成員函數(shù),都只能引用,不能改變它們?;蛘邔⑦@些數(shù)據(jù)成員所屬的對(duì)象聲明成const,只讓本對(duì)象的const 成員函數(shù)可引用,但不能改變。如果一個(gè)對(duì)象被定義成了常對(duì)象,只能調(diào)用其

32、中的const成員函數(shù),不能調(diào)用非const成員函數(shù)。常成員函數(shù)不能調(diào)用另一個(gè)非const成員函數(shù)3.6 共用數(shù)據(jù)的保護(hù)指向?qū)ο蟮某V羔樖裁磿r(shí)候需要常指針讓其指向?qū)ο螅咳绻雽⒁粋€(gè)指針變量與一個(gè)對(duì)象固定地聯(lián)系在一起,以防止誤操作;往往用常指針作為函數(shù)的形參,目的是不允許在函數(shù)執(zhí)行過(guò)程中改變指針值,使其始終指向原來(lái)的對(duì)象。將指向?qū)ο蟮闹羔樧兞柯暶鳛閏onst ,并將之初始化,可以使指針值恒定為初始值,即其指向始終不變。如Time t1(10,12,14), t2; /定義對(duì)象Time * const ptr = &t1; / 定義常指針,恒定指向t1對(duì)象ptr = &t2; / 錯(cuò)誤,常指針不能

33、改變指向定義一個(gè)指向?qū)ο蟮某V羔樀母袷綖椋侯?lèi)名 * const 指針變量名 = 對(duì)象地址;指向?qū)ο蟮某V羔槪@個(gè)變量的值是一個(gè)對(duì)象的地址,他不允許被改變,但所指對(duì)象的內(nèi)容可以改變。3.6 共用數(shù)據(jù)的保護(hù)指向常對(duì)象的指針定義指向常對(duì)象的指針格式:const 類(lèi)名 * 指針名;這和C語(yǔ)言中指向常變量的指針是一樣的。只需將上述格式中的類(lèi)名換成類(lèi)型名就行了。我們不妨在一起作如下討論:如果一個(gè)變量被聲明為常對(duì)象(/ 常變量),只能用指向常對(duì)象(/ 常變量)的指針指向它。如:const char c = “boy”; / 定義const型的常字符數(shù)組const char * p1; / p1為指向常字符變

34、量的指針p1 = c; / 合法,p1指向常變量 char * p2 = c / 非法,p2不是指向常變量的指針指向常變量的指針如果指向了非const對(duì)象,其指向的對(duì)象值不能用指針改變,可以用非指針?lè)绞礁淖儭ime t1(10,12,14); / 定義Time類(lèi)對(duì)象t1,它不是常對(duì)象const Time *p = &t1; / p是指向常對(duì)象t1 的指針 t1.hour = 18; / 合法,t1不是常量(*p).hour = 18; / 非法,不能通過(guò)指針改變t1的值3.6 共用數(shù)據(jù)的保護(hù)用指針變量作形參時(shí),形參和實(shí)參的對(duì)應(yīng)關(guān)系見(jiàn)下表形參實(shí)參是否合法指針?biāo)缸兞恐的芊窀淖冎赶蚍莄onst變

35、量或非const對(duì)象的指針?lè)莄onst變量的地址/非const對(duì)象的地址合法可以const變量的地址/const對(duì)象的地址非法/指向常變量或常對(duì)象的指針?lè)莄onst變量的地址/非const對(duì)象的地址合法不可以const變量的地址/const對(duì)象的地址合法不可以3.6 共用數(shù)據(jù)的保護(hù)例如: const char str = “boy”; / str是常數(shù)組名 void func(char * ptr); / 函數(shù)形參為指向非const變量的指針 func (str); / 非法,實(shí)參是常變量指針,形參是非const變量指針出錯(cuò)原因:形參是非指向非const型變量的指針,在函數(shù)中可以也可能改變指針

36、所指變量值,而實(shí)參是指向常變量的指針,不能被改變,發(fā)生矛盾。3.6 共用數(shù)據(jù)的保護(hù)指向常對(duì)象的指針最常用于函數(shù)的形參,目的是保護(hù)形參指針?biāo)傅膶?duì)象,使它在函數(shù)執(zhí)行過(guò)程中不被修改。如void main( ) void func(const Time * p); / func的形參是指向常對(duì)象的指針 Time t1(10,12,14); func(&t1); /合法,實(shí)參是 非const 對(duì)象t1 的地址 return;void func( const Time * P) p-hour = 18; / 錯(cuò)誤,指向的常對(duì)象被修改了 couthourendl;如果func形參不是指向const 型的T

37、ime對(duì)象的指針,即沒(méi)有const限定詞,則t1的hour就可以被修改。3.6 共用數(shù)據(jù)的保護(hù)有人可能會(huì)問(wèn),我不將func函數(shù)的形參定義為const型對(duì)象,只將 t1 定義為const 型對(duì)象,不是也能保護(hù) t1 在func中不被篡改嗎?不行,會(huì)出現(xiàn)編譯錯(cuò)誤。因?yàn)橹赶蚍莄onst 對(duì)象的指針不能指向const 對(duì)象;同理,指向非const 變量的指針不能指向const 變量。不能通過(guò)指向常對(duì)象的指針改變所指對(duì)象的值,但指針變量本身的值可以改變。3.6 共用數(shù)據(jù)的保護(hù)何時(shí)使用指向常對(duì)象的指針?何時(shí)使用常對(duì)象?當(dāng)希望在調(diào)用函數(shù)時(shí)對(duì)象的值不能被修改,就應(yīng)該把形參定義為指向常對(duì)象的指針,同時(shí)用對(duì)象的地

38、址做實(shí)參,而實(shí)參對(duì)象可以是const型,也可以是非 const型。如果要求對(duì)象不僅在函數(shù)調(diào)用過(guò)程中不被修改,而且在整個(gè)程序運(yùn)行時(shí)不被修改,就應(yīng)該把該對(duì)象定義成常對(duì)象。3.6 共用數(shù)據(jù)的保護(hù)對(duì)象的常引用前面講過(guò),引用主要是用于函數(shù)調(diào)用,將改變后的變量值帶回到被調(diào)用的函數(shù)外。但如果不希望在函數(shù)中修改參數(shù),可以把引用型形參定義成 const 型:函數(shù)返回類(lèi)型 函數(shù)名( const 形參類(lèi)型 & 形參名);則在函數(shù)中不能改變形參值,也就不能改變對(duì)應(yīng)的實(shí)參值。什么時(shí)候使用常指針和長(zhǎng)引用?使用常指針或常引用作為函數(shù)參數(shù),既能保證數(shù)據(jù)安全,不被修改;調(diào)用函數(shù)時(shí)又能不必建立實(shí)參的拷貝,提高了程序運(yùn)行效率,節(jié)省

39、了內(nèi)存空間。3.6 共用數(shù)據(jù)的保護(hù)const 數(shù)據(jù)小結(jié)形式含義Time const t1;const Time t1; t1是常對(duì)象,其值在任何情況下不能改變void Time:func( ) const func是Time類(lèi)中的常成員函數(shù),可以引用,但不能修改本類(lèi)中的數(shù)據(jù)成員Time * const p; p是指向Time對(duì)象的常指針,p的值,即p的指向不能改變Const Time *p; p是指向Time類(lèi)常對(duì)象的指針,其指向的對(duì)象的值不能通過(guò)指針來(lái)改變const Time &t1 = t; t1是Time類(lèi)對(duì)象t的常引用,函數(shù)中不能改變實(shí)參值3.7 對(duì)象的動(dòng)態(tài)建立和釋放問(wèn)題的提出:前面我

40、們所學(xué)創(chuàng)建對(duì)象的方法都是靜態(tài)的,它們?cè)诔绦?運(yùn)行過(guò)程中所占用的內(nèi)存空間不能被釋放。比如,在一個(gè)函數(shù)中定義了一個(gè)對(duì)象,只有在函數(shù)結(jié)束時(shí),該對(duì)象才能被釋放。有時(shí)候,人們希望對(duì)象的創(chuàng)建和釋放是在程序運(yùn)行時(shí),由運(yùn)行程序的人決定,比如,鏈表結(jié)構(gòu)的建立和刪除,這就需要?jiǎng)討B(tài)建立和釋放對(duì)象。C+語(yǔ)言用new、delete 這兩個(gè)運(yùn)算符來(lái)實(shí)現(xiàn)。內(nèi)存的分配和釋放,也用來(lái)實(shí)現(xiàn)對(duì)象的建立與撤消。3.7 對(duì)象的動(dòng)態(tài)建立和釋放動(dòng)態(tài)建立對(duì)象的方法:如果已經(jīng)定義了一個(gè) Box 類(lèi),可以用new 運(yùn)算符動(dòng)態(tài)地創(chuàng)建一個(gè) Box 對(duì)象:new Box;系統(tǒng)執(zhí)行此語(yǔ)句時(shí),首先開(kāi)辟一段內(nèi)存空間,并在此空間中存放一個(gè) Box 類(lèi)對(duì)象,同

41、時(shí)運(yùn)行該類(lèi)的構(gòu)造函數(shù),以初始化該對(duì)象,然后返回一個(gè)指向該對(duì)象的指針值。但此時(shí)用戶(hù)還不能訪(fǎng)問(wèn)這個(gè)對(duì)象,因?yàn)樗葲](méi)有對(duì)象名,用戶(hù)也不知道它的地址。這種對(duì)象稱(chēng)為“無(wú)名對(duì)象”。我們應(yīng)該這樣做:Box *pt; / 定義一個(gè)指向Box類(lèi)對(duì)象的指針ptpt = new Box; / 創(chuàng)建一個(gè)Box對(duì)象,將新對(duì)象的指針值賦給ptcout height endl;3.7 對(duì)象的動(dòng)態(tài)建立和釋放用new 動(dòng)態(tài)創(chuàng)建的對(duì)象一般沒(méi)有對(duì)象名,只能通過(guò)指針訪(fǎng)問(wèn)。在執(zhí)行new 運(yùn)算時(shí),如果內(nèi)存不足,則創(chuàng)建失敗。大多數(shù)C+編譯系統(tǒng)都讓 new 返回一個(gè)0指針,表示內(nèi)存不足,操作失敗。動(dòng)態(tài)撤消對(duì)象的方法:由new 創(chuàng)建的對(duì)象不再

42、需要時(shí),可以由delete運(yùn)算符釋放。上例pt的釋放方法為:delete pt;這樣就撤消了pt指向的對(duì)象。在執(zhí)行 delete運(yùn)算符時(shí),在釋放空間以前,系統(tǒng)自動(dòng)調(diào)用析構(gòu)函數(shù),完成有關(guān)善后清理工作。3.8 對(duì)象的賦值與復(fù)制對(duì)象的賦值對(duì)象之間的賦值是通過(guò)運(yùn)算符“=”進(jìn)行的,其過(guò)程是將一個(gè)對(duì)象的成員復(fù)制給另一同類(lèi)對(duì)象的對(duì)應(yīng)成員。對(duì)象賦值格式:對(duì)象名1=對(duì)象名2對(duì)象的復(fù)制C+可以根據(jù)一個(gè)已知的對(duì)象快速地復(fù)制出多個(gè)完全相同的對(duì)象。比如:Box box2(box1);其作用就是對(duì)象的克隆,即用一個(gè)已知的對(duì)象 box1復(fù)制出一個(gè)完全相同的新對(duì)象 box2。對(duì)象復(fù)制的格式:類(lèi)名 被克隆出來(lái)的新對(duì)象名(已有的

43、對(duì)象名);3.8 對(duì)象的賦值與復(fù)制從上面的一般形式可以看出,復(fù)制對(duì)象是一種特殊的構(gòu)造對(duì)象方法,其構(gòu)造參數(shù)參數(shù)不是一般變量,而必須是一個(gè)對(duì)象!請(qǐng)看:/ 復(fù)制構(gòu)造函數(shù)Box:Box ( const Box &b) height = b.height; width = b.width; height = b.height;復(fù)制構(gòu)造函數(shù)也是構(gòu)造函數(shù),它只有一個(gè)參數(shù),這個(gè)參數(shù)是本類(lèi)已有對(duì)象,而且采用常引用形式,使參數(shù)不能被改變。復(fù)制構(gòu)造函數(shù)的作用是將實(shí)參對(duì)象的各個(gè)數(shù)據(jù)成員值一一賦予給新的對(duì)象中對(duì)應(yīng)的數(shù)據(jù)成員。3.8 對(duì)象的賦值與復(fù)制C+還使用另一種方便的對(duì)象復(fù)制形式,形式為:類(lèi)名 目標(biāo)對(duì)象名 = 源象名

44、;如:Box box2 = box1, box3 = box2;對(duì)象的賦值與復(fù)制的不同點(diǎn)對(duì)象的賦值:是在已經(jīng)存在的對(duì)象之間進(jìn)行數(shù)據(jù)賦值,因此必須先定義,再賦值;參數(shù)表是一般變量對(duì)象的復(fù)制:從無(wú)到有地建立一個(gè)相同的新對(duì)象,參數(shù)只有一個(gè),而且是已有的同類(lèi)對(duì)象。普通構(gòu)造函數(shù)與拷貝構(gòu)造函數(shù)的不同:參數(shù)不同:普通構(gòu)造函數(shù):類(lèi)名(形參表列); / 普通構(gòu)造函數(shù)的聲明拷貝構(gòu)造函數(shù):類(lèi)名(類(lèi)名 & 對(duì)象名); / 復(fù)制構(gòu)造函數(shù)的聲明返回類(lèi)型不同拷貝構(gòu)造函數(shù)返回一個(gè)對(duì)象。3.8 對(duì)象的賦值與復(fù)制什么時(shí)候使用復(fù)制構(gòu)造函數(shù)?程序中需要建立一個(gè)對(duì)象,并用另一個(gè)已知對(duì)象初始化它,系統(tǒng)自動(dòng)調(diào)用復(fù)制構(gòu)造函數(shù);當(dāng)函數(shù)的參數(shù)是

45、類(lèi)的對(duì)象時(shí),系統(tǒng)自動(dòng)調(diào)用復(fù)制構(gòu)造函數(shù);void main( ) Box b1(12,13,15); func(b1); 當(dāng)函數(shù)的返回值是類(lèi)的對(duì)象,系統(tǒng)自動(dòng)調(diào)用復(fù)制構(gòu)造函數(shù)Box f( ) Box b1(12,14,16); return b1; / 返回值是Box類(lèi)的對(duì)象void main ( ) Box b2; b2 = f( ); / f函數(shù)返回Box類(lèi)的臨時(shí)對(duì)象,并將它賦值給b2由于b1是在函數(shù) f 中定義的,函數(shù)f 結(jié)束時(shí),b1的生命期就結(jié)束了。因此不能將b1 帶回給main函數(shù),實(shí)際上,在f 結(jié)束前,執(zhí)行return 語(yǔ)句時(shí),復(fù)制一個(gè)b1一樣的臨時(shí)對(duì)象,然后將它賦值給b2。#incl

46、ude using namespace std;class student string name; int age; float score; static int cnt;public: student(string n,int a,float s) name=n; age=a; score=s; cnt+; cout1+endl; student(const student &s); student() cnt-; coutcnt.endl; void show();void student:show() coutname age scoreendl;student:student(co

47、nst student &s) name=; age=s.age; score=s.score; cnt+; cout2*endl; int student:cnt=0;void main() student s3= student(zhangsan,20,90.0), student(zhaohong,21,70.0), student(lilongxin,19,70.0) ; for (int i=0;i3;i+) si.show();3.9 靜態(tài)成員在C語(yǔ)言中,如果想在多個(gè)函數(shù)中共享一個(gè)變量值,我們一般用全局變量。但由于全局變量破壞了封裝性,安全得不到保證,在C+中不提倡使用

48、全局變量,我們可以使用靜態(tài)的數(shù)據(jù)成員來(lái)達(dá)到這個(gè)目的。靜態(tài)數(shù)據(jù)成員靜態(tài)數(shù)據(jù)成員以 static 關(guān)鍵字定義。例如:class student public:int display( );private:static int count;char name10;int age;3.9 靜態(tài)成員將對(duì)象中的 count 數(shù)據(jù)成員定義成 static 型,它就被同一種類(lèi)的各個(gè)對(duì)象所共有,而不只屬于某一個(gè)對(duì)象。靜態(tài)數(shù)據(jù)成員只占份內(nèi)存空間,而不是各個(gè)對(duì)象個(gè)擁有一份內(nèi)存空間!每個(gè)對(duì)象都可以引用這個(gè)靜態(tài)數(shù)據(jù)成員。靜態(tài)數(shù)據(jù)成員的值對(duì)各個(gè)對(duì)象都是一樣的。如果改變它的值,則在各個(gè)對(duì)象中這個(gè)數(shù)據(jù)成員的值都同時(shí)改變。3.

49、9 靜態(tài)成員說(shuō)明:在為對(duì)象分配空間時(shí),不分配靜態(tài)數(shù)據(jù)成員的空間,因?yàn)樗粚儆谌魏螌?duì)象。只要類(lèi)中定義了靜態(tài)數(shù)據(jù)成員,即使不定義對(duì)象,編譯系統(tǒng)也要為靜態(tài)數(shù)據(jù)成員開(kāi)辟內(nèi)存空間。C語(yǔ)言中,我們知道,如果在一個(gè)函數(shù)中定義了一個(gè)靜態(tài)變量,在函數(shù)結(jié)束時(shí)該靜態(tài)變量不被釋放,并保留其值。靜態(tài)數(shù)據(jù)成員也是這樣,它不隨對(duì)象的建立而分配空間,也不隨對(duì)象的撤消而釋放空間,其值也被保留。靜態(tài)數(shù)據(jù)成員在程序被編譯時(shí)就分配了空間,在程序結(jié)束時(shí),才釋放空間。靜態(tài)數(shù)據(jù)成員可以被初始化,但只能在內(nèi)體之外初始化:數(shù)據(jù)類(lèi)型 類(lèi)名:靜態(tài)數(shù)據(jù)成員名 = 初值;不必在初始化語(yǔ)句中加 static 關(guān)鍵字,不能用參數(shù)初始化表初始化靜態(tài)數(shù)據(jù)成員

50、:student (int c, char *p, int a) : count(c) / 錯(cuò)誤,count是靜態(tài)數(shù)據(jù)成員3.9 靜態(tài)成員靜態(tài)數(shù)據(jù)成員既可以通過(guò)類(lèi)名引用,也可以通過(guò)對(duì)象名引用。#include #include class Student public: static int count; /靜態(tài)數(shù)據(jù)成員 char name40; Student(char* pN =no name) coutCreate one student pNn; strcpy(name,pN); count +; coutcountendl; Student ( ) coutdestruct one

51、student “ namen; count -; coutcountendl; ; int Student:count=0; void main( ) Student s1(zhangsan); coutStudent:count“ Student:count endl; Student s2(lisi); coutStudent:count“ Student:count endl; 3.9 靜態(tài)成員靜態(tài)成員函數(shù)在類(lèi)的定義中,成員函數(shù)前如果加了 static 限定詞,該成員函數(shù)就成為靜態(tài)成員函數(shù)。例:static int volume( );用途:靜態(tài)成員函數(shù)的作用不是為了對(duì)象之間的溝通,主

52、要是為了引用本類(lèi)中的靜態(tài)數(shù)據(jù)成員。它可以直接引用本類(lèi)的靜態(tài)數(shù)據(jù)成員。靜態(tài)成員函數(shù)與普通成員函數(shù)的區(qū)別:靜態(tài)成員函數(shù)沒(méi)有 this 指針,由此決定靜態(tài)成員函數(shù)不能訪(fǎng)問(wèn)本類(lèi)中的非靜態(tài)數(shù)據(jù)成員,除非用“對(duì)象名.非靜態(tài)數(shù)據(jù)成員”的形式。3.9 靜態(tài)成員靜態(tài)成員函數(shù)示例#include #include class Student protected: static int count; /靜態(tài)數(shù)據(jù)成員 char name40; public: Student(char* pN =no name) coutCreate one student pNn; strcpy(name,pN); count +;

53、 coutcountendl; Student( ) coutdestruct one student “ namen; count -; coutcountendl; static int number( ) / 靜態(tài)成員函數(shù) return count; / 直接引用本類(lèi)的靜態(tài)數(shù)據(jù)成員; int Student:count=0; void fn( ) Student s1(zhangsan); Student s2(lisi); coutStudent:number( ) endl; couts1.number( ) endl; couts2.number( ) endl; void main( ) fn( ); coutStudent:number “ Student:number( ) i=a;void X:member_func(int a) /member function definition i=a;一個(gè)友元的綜合示例#include

溫馨提示

  • 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. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論