3類與對象電子科技計算機學院軟件_第1頁
3類與對象電子科技計算機學院軟件_第2頁
3類與對象電子科技計算機學院軟件_第3頁
3類與對象電子科技計算機學院軟件_第4頁
3類與對象電子科技計算機學院軟件_第5頁
已閱讀5頁,還剩100頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、類與對象C+與C最大的不同在于C+增加了面向?qū)ο蟮母拍?。C+允許用戶定義新的抽象數(shù)據(jù)類型類類型,它將一組數(shù)據(jù)和與這些數(shù)據(jù)相關(guān)的操作封裝在一起,實現(xiàn)了面向?qū)ο蠹夹g(shù)中的核心概念數(shù)據(jù)封裝。2022/9/162抽象抽象是對具體對象(問題)進行概括,抽出這一類對象的公共性質(zhì)并加以描述的過程。先注意問題的本質(zhì)及描述,其次是實現(xiàn)過程或細節(jié)。數(shù)據(jù)抽象:描述某類對象共有的屬性或狀態(tài)。行為抽象:描述某類對象共有的行為特征或具有的功能。2022/9/163抽象實例:時鐘數(shù)據(jù)抽象:具有表明當前時間的時、分、秒行為抽象:具有設置時間和顯示時間兩個最基本的功能2022/9/164抽象實例:人數(shù)據(jù)抽象:姓名、年齡、性別等行

2、為抽象:生物屬性:吃飯、穿衣、睡覺、行走等行為社會屬性:工作、學習等行為2022/9/165在研究問題時,側(cè)重點不同,可能會產(chǎn)生不同的抽象結(jié)果;解決同一問題時要求不同,也會產(chǎn)生不同的抽象結(jié)果。例如:如果開發(fā)一個人事管理軟件,那么關(guān)心的是員工的姓名、性別、工齡、工資、工作部門等相關(guān)信息。如果開發(fā)學籍管理軟件,那么關(guān)心的是學生的姓名、性別、年齡、籍貫、所在學院等相關(guān)信息。因此,抽象是相對,而非絕對的。2022/9/166如何實現(xiàn)抽象?抽象定義了一個事物的本質(zhì)特征,那么從軟件設計的角度又如何對抽象出來的結(jié)果進行描述呢?封裝可以實現(xiàn)抽象。封裝就是將數(shù)據(jù)和操作這些數(shù)據(jù)的函數(shù)進行有機地結(jié)合。C+的解決方案

3、:用類來實現(xiàn)封裝機制2022/9/167定義和使用類的基本過程第一步:進行抽象第二步:定義類第三步:實現(xiàn)類第四步:使用類2022/9/168類的定義:類的成員構(gòu)成2022/9/169class ClassName數(shù)據(jù)成員函數(shù)成員;類是一種抽象數(shù)據(jù)類型,聲明形式如下:關(guān)鍵字class用于聲明一個類類型用于表達數(shù)據(jù)抽象用于表達行為抽象類定義舉例:時鐘類2022/9/1610class Clockint Hour, Minute, Second;void SetTime( int h, int m, int s ); void ShowTime( );類成員的訪問控制什么是“類內(nèi)”和“類外”在類定義

4、之內(nèi)稱為類內(nèi)在類定義之外稱為類外數(shù)據(jù)封裝的目的就是信息隱蔽。為了達到信息隱蔽,在C+類中,并非所有的成員都是對外可見的(或者說,是類外可以訪問的)。通過設置成員的訪問控制屬性來實現(xiàn)對類成員的訪問控制。這些控制屬性有:public、protected、private2022/9/1611類的定義:對成員的訪問控制2022/9/1612class ClassNamepublic:公有成員protected:保護成員private:私有成員;公有成員在關(guān)鍵字public后面聲明,它們是類與外部的接口,任何類內(nèi)、類外函數(shù)都可以訪問公有數(shù)據(jù)和函數(shù)。2022/9/1613class Clockpublic

5、: void SetTime( int h, int m, int s );/公有成員函數(shù) void ShowTime( ); /公有成員函數(shù);私有成員在關(guān)鍵字private后面聲明,只允許本類中的函數(shù)(即類內(nèi)函數(shù))訪問,而類外的任何函數(shù)都不能訪問。2022/9/1614class Clockprivate:int Hour, Minute, Second;/私有數(shù)據(jù)成員;保護成員在關(guān)鍵字protected后面聲明的數(shù)據(jù)成員或成員函數(shù)。與private類似,其差別表現(xiàn)在繼承與派生時對派生類的影響不同。2022/9/1615類定義舉例:時鐘類2022/9/1616class Clockpubli

6、c: void SetTime( int h, int m, int s ); void ShowTime( );private: int Hour, Minute, Second;類的實現(xiàn)2022/9/1617實現(xiàn)一個類,就是按照所設定的功能語義去實現(xiàn)類中的每一個成員函數(shù)。2022/9/1618class Clockprivate: int Hour, Minute, Second;public: void SetTime( int h, int m, int s ) Hour=h; Minute=m; Second=s; void ShowTime( ) cout“Current Time

7、:” coutHour“:” Minute“:” Second endl;在類內(nèi)實現(xiàn)成員函數(shù),編譯器按內(nèi)聯(lián)函數(shù)處理在類內(nèi)實現(xiàn)成員函數(shù),編譯器按內(nèi)聯(lián)函數(shù)處理或者:2022/9/1619class Clockprivate: int Hour, Minute, Second;public: void SetTime( int h, int m, int s );/給出函數(shù)原型 void ShowTime( ); /給出函數(shù)原型;void Clock:SetTime( int h, int m, int s ) Hour=h; Minute=m; Second=s;void Clock:ShowTi

8、me( )cout“Current Time:”coutHour“:” Minute“:” Second 公有成員函數(shù)名(參數(shù)列表); 對象的指針-公有數(shù)據(jù)成員2022/9/1621舉例:一個比較完整的Clock類2022/9/1622/定義Clock類class Clockprivate: int Hour, Minute, Second;public: void SetTime( int h, int m, int s); void addHour(int h); void addMinute(int m); void addSecond(int s); void ShowTime( );

9、 ;2022/9/1623/實現(xiàn)Clock類中的成員函數(shù)void Clock:SetTime( int h, int m, int s ) Hour=h; Minute=m; Second=s;void Clock:addHour( int h ) Hour += h; void Clock:addMinute( int m ) Minute += m; void Clock:addSecond( int s ) Second += s; void Clock:ShowTime( )cout“Current Time:”;coutHour“:” Minute“:” Secondendl;202

10、2/9/1624/使用Clock類void main( )Clock clock_1, clock_2;clock_1. SetTime( 9 , 5 , 25 );clock_2. SetTime( 15 , 16 , 45 );clock_1. addHour( 3 );clock_2. addMinute( 8 );clock_1. ShowTime( );clock_2. ShowTime( );程序輸出: Current Time:12:5:25 Current Time:15:24:45總結(jié):定義和使用類類型的過程抽象:對事物進行抽象定義類:根據(jù)抽象的結(jié)果定義類的特性實現(xiàn)類:實現(xiàn)類

11、中成員函數(shù)的邏輯使用類:在程序中定義類的實例,使用類的公有成員。2022/9/1625在定義類時,把可以被外部訪問的成員說明為public屬性,作為外部訪問類中成員的接口。把不能被外部訪問的成員說明為private或protected屬性。2022/9/1626私有成員公有成員類對外的接口保護成員請思考以下情況能調(diào)用下面語句嗎?clock_1.Hour=21;如果將ShowTime說明為private屬性,還能調(diào)用如下語句嗎?clock_2.ShowTime();2022/9/1627練習一設計一個三角形類CTriangle,該類滿足下述要求:a)有一個成員函數(shù)SetEdge,用于設置三角形的

12、邊。b)有一個成員函數(shù)GetArea,用于獲得三角形的面積。c)有一個成員函數(shù)GetCircumference,用于獲得三角形的周長。在main函數(shù)中,實例化一個Ctriangle類的對象,將三條邊分別為3、4、5,然后將其面積和周長顯示在屏幕上。2022/9/1628備注:1三角形面積的計算方式如下: a、b、c分別為三條邊,S代表面積,p=(a+b+c)/2,那么S2=p(p-a)(p-b)(p-c)。2求開平方的庫函數(shù)是sqrt,需要包含math.h頭文件,使用方式的舉例如下:int a, b; b=36; a=sqrt(b); 那么a的值為62022/9/1629幾點說明在聲明類時,具

13、有不同訪問屬性的成員可以按任意順序出現(xiàn)。2022/9/1630class Clockprivate: int Hour, Minute, Second;public: void SetTime( int h, int m, int s ); void ShowTime( );protected:;修飾訪問屬性關(guān)鍵字可以多次出現(xiàn)。2022/9/1631class Clockpublic: void SetTime( int h, int m, int s ); private: int Hour, Minute, Second;public: void ShowTime( );一個成員只能具有一

14、種訪問屬性,否則會出現(xiàn)歧異。2022/9/1632class Clockpublic: void SetTime( int h, int m, int s ); void ShowTime( );private: void ShowTime( );int Hour, Minute, Second;例子:簡單int數(shù)組類2022/9/1633/數(shù)組類的定義const int ARRAY_SIZE=4;class MyArrayint dataARRAY_SIZE;public:int getArraySize();int setVal(int pos,int val);int getMaxVal

15、();int getMinVal();2022/9/1634/數(shù)組類的實現(xiàn)int MyArray:getArraySize()return ARRAY_SIZE;int MyArray:setVal(int pos,int val)if(posARRAY_SIZE)return -1;datapos=val;return 0;2022/9/1635/數(shù)組類的實現(xiàn)(續(xù))int MyArray:getMaxVal()int temp=data0; for(int i=1;itemp)temp=datai;return temp;int MyArray:getMinVal()int temp=dat

16、a0; for(int i=1;iARRAY_SIZE;i+)if(dataitemp)temp=datai;return temp;2022/9/1636/數(shù)組類的使用int main()MyArray array;int i,size,v,max,min;size=array.getArraySize();coutplease input size numbers:endl; for(i=0;iv;array.setVal(i,v);max=array.getMaxVal();min=array.getMinVal();coutmax value is : maxendl;coutmin

17、value is : minendl;return 0;改造:為簡單int數(shù)組類增加公用的私有函數(shù)2022/9/1637/數(shù)組類的定義:增加公用的私有函數(shù)const int ARRAY_SIZE=4;class MyArrayint dataARRAY_SIZE;int getVal(int condition);public:int getArraySize();int setVal(int pos,int val);int getMaxVal();int getMinVal();2022/9/1638/數(shù)組類的實現(xiàn):增加和調(diào)用公用的私有函數(shù)int MyArray:getVal(int co

18、ndition)int temp=data0; for(int i=1;itemp)temp=datai;elseif(datai SetTime( 9 , 5 , 25 );p- ShowTime( );p- SetTime( 10 , 3 , 28 );p- ShowTime( );關(guān)鍵字thisC+為每個非靜態(tài)成員函數(shù)提供一個this指針。this指針是一個隱含的指針,它指向了正在被成員函數(shù)操作的那個對象。this指針不能顯式聲明,它只是非靜態(tài)成員函數(shù)的一個形參。2022/9/1641this指針舉例2022/9/1642class Counterint value;public:voi

19、d setValue( int value )this-value=value;class Counterint value;public:void setValue( int v )value=v;void main() Counter obj1,obj2;obj1.setValue(1);obj2.setValue(2);編譯器做了特殊處理2022/9/1643class Counterint value;public: void setValue(Counter *this, int v )this-value=v;class Counterint value;public:void s

20、etValue( int v )value=v;void main() Counter obj1,obj2;obj1.setValue(1);obj2.setValue(2);void main() Counter obj1,obj2;obj1.setValue(&obj1,1);obj2.setValue(&obj2,2);構(gòu)造函數(shù)和析構(gòu)函數(shù)類的數(shù)據(jù)成員是不能在定義時直接初始化的,以Clock類為例:2022/9/1644class Clockprivate: int Hour=0, Minute=0, Second=0;/錯誤;當Clock類被實例化時,如何初始化對象的狀態(tài),即如何初始化H

21、our、Minute、Second三個成員呢?一種可行的方式就是顯式調(diào)用初始化函數(shù)。2022/9/1645Clock clock1;clock1. SetTime(21, 34, 43);但是這種方式存在一些不好的情況:程序員可能會忘記調(diào)用SetTime()函數(shù),導致對象沒有被初始化。構(gòu)造函數(shù)實際上,我們更希望這個初始化工作能夠自動進行。類的構(gòu)造函數(shù)提供了這種自動化功能。構(gòu)造函數(shù)是類的一種特殊成員,函數(shù)名和類名相同,沒有返回類型,可以有參數(shù)。當創(chuàng)建類的一個新對象時,構(gòu)造函數(shù)被自動調(diào)用,完成對象的初始化工作。2022/9/1646例:為Clock類添加構(gòu)造函數(shù)class Clockprivate

22、: int Hour, Minute, Second;public:Clock(int h, int m, int s);2022/9/1647構(gòu)造函數(shù)初始化數(shù)據(jù)成員的兩種方式賦值語句的方式:2022/9/1648Clock(int h, int m, int s) Hour = h;Minute = m; Second = s; 表達式表的方式:Clock(int h, int m, int s): Hour(h), Minute(m), Second(s) 傳給構(gòu)造函數(shù)實參的兩種方式如果構(gòu)造函數(shù)帶有參數(shù),那么在創(chuàng)建對象時必須給出對應的實參。如果構(gòu)造函數(shù)僅有一個參數(shù):className ob

23、j = parameter;如果構(gòu)造函數(shù)有一個或多個參數(shù):className obj(parameter list);如果構(gòu)造函數(shù)有參數(shù),但是在創(chuàng)建對象時又不給出對應的實參,此時編譯出錯。2022/9/1649舉例class Clockprivate: int Hour, Minute, Second;public: Clock(int h, int m, int s);2022/9/1650void main( )Counter counter1(8);Counter counter2=9;Clock clock1(3, 5, 1);Clock clock2( );/錯誤class Coun

24、terprivate:int value;public:Counter(int v):value(v) ;重載構(gòu)造函數(shù)一個類可以提供多個構(gòu)造函數(shù),但它們的參數(shù)表必須不同。重載的目的是為了滿足不同的初始化需要。2022/9/1651class Clockprivate: int Hour,Minute, Second;public:Clock(int h, int m, int s);Clock( );Clock(char *timestr);void main( )Clock clock1(23, 12, 0);Clock clock2( );Clock clock3(“14:45:32” )

25、;具有缺省參數(shù)的構(gòu)造函數(shù)構(gòu)造函數(shù)也可以有缺省參數(shù)。如果在類外實現(xiàn)該函數(shù)時,就不能再說明缺省值了。2022/9/1652class Clockprivate: int Hour,Minute, Second;public:Clock(int h = 0, int m = 0, int s = 0);Clock(const char *timestr); Clock();請思考一下,這個類還能再有一個沒有任何參數(shù)的構(gòu)造函數(shù)嗎?即:Clock();缺省的構(gòu)造函數(shù)對于沒有構(gòu)造函數(shù)的類,編譯器將會自動為它生成一個沒有參數(shù)的構(gòu)造函數(shù),該函數(shù)不做任何工作。2022/9/1653class Clockpriv

26、ate: int Hour, Minute, Second;析構(gòu)函數(shù)與構(gòu)造函數(shù)相對的是析構(gòu)函數(shù)。C+通過析構(gòu)函數(shù)來處理對象被銷毀時的清理工作。析構(gòu)函數(shù)沒有返回類型,沒有參數(shù),函數(shù)名是在類名前加“”。析構(gòu)函數(shù)將會在對象的生存期結(jié)束后被自動調(diào)用。如果沒有進行顯式說明,系統(tǒng)將會生成一個不做任何事的缺省的析構(gòu)函數(shù)。2022/9/1654舉例:為Clock類添加析構(gòu)函數(shù)class Clockprivate: int Hour, Minute, Second;public: Clock(int h=12, int m=0, int s=0);Clock( );Clock:Clock( )cout“Cloc

27、k obj destroyed!”endl;2022/9/1655void func( )Clock obj1,obj2;void main()func();/輸出: Clock obj destroyed! Clock obj destroyed!2022/9/1656析構(gòu)函數(shù)的典型用法class MyStringprivate: int len;char *buf;public: MyString(int n);void copy(char *src);MyString:MyString( int n)len=n;buf=new charn;void MyString:copy(char

28、*src)strcpy(buf,src);2022/9/1657void func()MyString obj( 64 );obj.copy(“helloworld”);void main()func( );!此時,obj的buf所指向的內(nèi)存空間沒有釋放class MyStringprivate: int len;char *buf;public: MyString(int n); MyString( );void copy(char *src);MyString:MyString( int n)len=n;buf=new charn;void MyString:copy(char *src)

29、strcpy(buf,src);MyString: MyString( )delete buf;2022/9/1658void func()MyString obj( 64 );obj.copy(“helloworld”);void main()func( );!當obj對象被釋放時,析構(gòu)函數(shù)被自動調(diào)用,buf所指向的內(nèi)存空間被釋放拷貝構(gòu)造函數(shù)構(gòu)造函數(shù)的參數(shù)可以是任意類型,如果將與自己同類的對象的引用作為參數(shù)時,該構(gòu)造函數(shù)就稱為拷貝構(gòu)造函數(shù)??截悩?gòu)造函數(shù)的特點:首先,它是一個構(gòu)造函數(shù),當創(chuàng)建對象時系統(tǒng)會自動調(diào)用它。其次,它將一個已經(jīng)創(chuàng)建好的對象作為拷貝構(gòu)造函數(shù)的參數(shù),并根據(jù)需要將該對象中的數(shù)據(jù)

30、成員逐一對應地賦值給新對象。2022/9/1659示例class Pointprivate: float x, y;public: Point(float a, float b) x=a; y=b; Point(Point &obj)x=obj.x;y=obj.y; ;void main()Point obj1( 5, 15);/調(diào)用Point(float , float )Point obj2(obj1);/調(diào)用Point(A&)Point obj3=obj2;/調(diào)用Point(A&)2022/9/1660缺省的拷貝構(gòu)造函數(shù)的應用2022/9/1661如果一個類沒有定義拷貝構(gòu)造函數(shù),那么C+

31、編譯器會為該類產(chǎn)生一個缺省的拷貝構(gòu)造函數(shù)。缺省的拷貝構(gòu)造函數(shù)使用位拷貝的方法來完成對象到對象的復制。也就是說,將第一個對象中的數(shù)據(jù)成員的值原封不動拷貝到第二個對象的數(shù)據(jù)成員中。a_objb_objBit Copy例:缺省的拷貝構(gòu)造函數(shù)的應用class Pointprivate: float x, y;public: Point(float a, float b) x=a; y=b; ;void main()Point obj1( 5, 15); /調(diào)用A(float, float)Point obj2(obj1); /調(diào)用缺省的拷貝構(gòu)造函數(shù)Point obj3=obj2; /調(diào)用缺省的拷貝構(gòu)造

32、函數(shù)2022/9/1662obj2是obj1的精確拷貝,obj3是obj2的精確拷貝缺省的拷貝構(gòu)造函數(shù)的缺點在大多數(shù)情況下,缺省拷貝構(gòu)造函數(shù)工作得很好,但在一些特殊的場合,它的表現(xiàn)將不盡人意。2022/9/1663class MyStringprivate: int len;char *buf;public: MyString(int n);MyString( );void copy(char *src);MyString:MyString( int n)len=n;buf=new charn;void MyString:copy(char *src)strcpy(buf,src);MyStr

33、ing:MyString( )delete buf;2022/9/1664void func()MyString obj1( 64 );obj1.copy(“helloworld”); MyString obj2=obj1;void main()func( );! 由于調(diào)用的是默認的拷貝構(gòu)造函數(shù),因此obj1和obj2中的buf指向同一內(nèi)存空間,當它們被釋放時,該內(nèi)存空間將被釋放兩次。改進辦法:增加拷貝構(gòu)造函數(shù)2022/9/1665class MyStringpublic: MyString(int n); MyString(MyString &obj); ;MyString:MyString

34、(MyString &obj)len = obj.len;buf=new char len ;strcpy( buf , obj.buf );通過自定義拷貝構(gòu)造函數(shù),可以準確地復制數(shù)據(jù),以免發(fā)生錯誤??截悩?gòu)造函數(shù)起作用的地方拷貝構(gòu)造函數(shù)除了在創(chuàng)建新對象時被調(diào)用外,還在以下情況被調(diào)用:對象作為函數(shù)參數(shù)函數(shù)返回對象2022/9/1666舉例2022/9/1667class Counterprivate: int value;public: Counter(int v) value=v; void add(int v) value+=v; void show( ) coutvalueendl; ;C

35、ounter func(Counter obj )obj.add(6);return obj;void main( ) Counter b1=5; Counter b2=func(b1); b1.show(); b2.show();輸出:5 11調(diào)用func(b1)時調(diào)用默認的拷貝構(gòu)造函數(shù)調(diào)用return obj時調(diào)用默認的拷貝構(gòu)造函數(shù)將func()返回值賦給b2時調(diào)用默認的拷貝構(gòu)造函數(shù)2022/9/16685b111temp11b25(11)objfunc(b1)return objb2=func(b1)對象數(shù)組與任何其它數(shù)據(jù)類型一樣,可以創(chuàng)建一個類的對象數(shù)組。例如:Clock clocks

36、10;通過下標訪問數(shù)組中的對象,進而訪問該對象的公有成員,例如:clocks3.ShowTime();2022/9/1669舉例2022/9/1670class Pointpublic: float x,y; Point( )x=0;y=0; Point(float a)x=a;y=0; Point(float a ,float b)x=a;y=b; void show( ) coutx“:”yendl; ;void main( ) Point array3;array1.x=5;array1.y=6;array1.show();輸出:5:6對象數(shù)組的初始化對象數(shù)組的初始化過程,實際上就是調(diào)用

37、構(gòu)造函數(shù)對每一個數(shù)組元素進行初始化的過程。如果在聲明數(shù)組時給出每一個數(shù)組元素的初始值,在初始化過程中就會調(diào)用最匹配的構(gòu)造函數(shù)。2022/9/1671舉例:對象數(shù)組初始化2022/9/1672class Pointpublic: Point( )x=0;y=0; Point(float a)x=a;y=0; Point(float a , float b)x=a;y=b; ;void main( )Point array3= Point(3,4), 5 ;初始化array0時調(diào)用的是Point(float ,float)構(gòu)造函數(shù)初始化array1時調(diào)用的是Point(float)構(gòu)造函數(shù)初始化a

38、rray2時調(diào)用的是Point( )構(gòu)造函數(shù)對象指針的加減操作2022/9/1673class Counterprivate: int value;public: Counter(int v) value=v; void show( ) coutvalueshow();p+;p-show();p+;p-show();輸出:5 6 7類類型作參數(shù)類型的三種方式對象本身作為參數(shù)由于C+采用傳值的方式傳遞參數(shù),因此使用對象本身參數(shù)時,形參是實參的一個拷貝。在這種情況下,最好顯式地為類定義一個拷貝構(gòu)造函數(shù),以免出現(xiàn)不容易發(fā)現(xiàn)的錯誤。2022/9/1674舉例:對象本身做函數(shù)參數(shù)2022/9/1675c

39、lass Counterprivate: int value;public: Counter(int v) value=v; void add(int v) value+=v; void show( ) coutvalueadd(6);輸出:5 11靜態(tài)成員當用關(guān)鍵字static說明一個類成員時,該成員稱為靜態(tài)成員。因此可以分為:靜態(tài)數(shù)據(jù)成員靜態(tài)成員函數(shù)2022/9/1678靜態(tài)數(shù)據(jù)成員類的所有對象共享靜態(tài)數(shù)據(jù)成員,因此無論建立多少個該類的對象,靜態(tài)數(shù)據(jù)成員只有一份拷貝。靜態(tài)數(shù)據(jù)成員屬于類,而不屬于具體的對象。2022/9/1679class ABCD /聲明靜態(tài)數(shù)據(jù)成員static int

40、s_value;int value;ABCD A ,B,C,D; Object AValueObject DvalueObject Bvalues_valueObject Cvalue靜態(tài)數(shù)據(jù)成員的定義和初始化在類內(nèi)只是靜態(tài)數(shù)據(jù)成員的聲明,但是靜態(tài)數(shù)據(jù)成員必須在類外定義,格式如下:類型 類名:靜態(tài)數(shù)據(jù)成員int ABCD:s_value;在定義靜態(tài)數(shù)據(jù)成員的時候可以對其進行初始化,方式如下:類型 類名:靜態(tài)數(shù)據(jù)成員int ABCD:s_value=6;2022/9/1680靜態(tài)數(shù)據(jù)成員的使用靜態(tài)數(shù)據(jù)成員也有public和private之分,由于靜態(tài)數(shù)據(jù)成員是屬于類的,因此:在類外,按如下形式訪

41、問public靜態(tài)數(shù)據(jù)成員: 類名:靜態(tài)數(shù)據(jù)成員ABCD:s_value+;在類內(nèi),可以直接訪問所有屬性的靜態(tài)數(shù)據(jù)成員特別地,當類對象不存在時,也可以訪問類的靜態(tài)數(shù)據(jù)成員。2022/9/1681例1:靜態(tài)數(shù)據(jù)成員的基本用法2022/9/1682class counterstatic int count;/聲明 public:void setcount(int num)count=num;void showcount()coutcount“ “;/定義int counter:count=0;void main()counter a, b;a.showcount();b.showcount();a

42、.setcount(34);a.showcount();b.showcount();/輸出:0 0 34 34靜態(tài)成員函數(shù)靜態(tài)成員函數(shù)的定義2022/9/1683class ABCDpublic:static void show_staticvalue();靜態(tài)成員函數(shù)只屬于一個類,它沒有this指針。靜態(tài)成員函數(shù)也可以聲明為public或private屬性。請思考能將構(gòu)造函數(shù)聲明為非public屬性嗎?如果能,將會出現(xiàn)什么情況?2022/9/1684class Clockprivate: int Hour, Minute, Second;Clock(int h, int m, int s);

43、void main()Clock aclock(1,2,3);編譯出錯,因為構(gòu)造函數(shù)是private屬性請思考試編程統(tǒng)計出一個類在程序中,實例化的對象個數(shù)?2022/9/1685舉例:靜態(tài)成員的應用如果有一個類MyClass,如何設計才能保證在程序運行中該類只能有一個實例?利用靜態(tài)成員可以解決該問題。2022/9/1686class MyClassprivate:static MyClass *instance;MyClass()public:static MyClass *getInstance() if(instance=NULL) instance=new MyClass(); retu

44、rn instance;MyClass *MyClass:instance=NULL;void main()MyClass *obj;obj=MyClass:getInstance();將構(gòu)造函數(shù)聲明為非public屬性,可以控制對象的生成!友元關(guān)系封裝的目的就是為了實現(xiàn)信息隱蔽。一個對象的私有成員只能被自己的成員訪問到。當類外的對象或函數(shù)要訪問這個類的私有成員時,只能通過該類提供的公有成員間接地進行。出于效率(而非技術(shù)上必須)的考慮,C+提供了友元機制來打破私有化的界限,即一個類的友元可以訪問到該類的私有成員。2022/9/1687友元函數(shù)問題的提出Point類代表“點”,考慮如下需求:需要

45、一個函數(shù)來計算任意兩點間的距離,那么這個函數(shù)該如何設計呢?2022/9/1688class Pointfloat x, y;public:Point( float xx=0, float yy=0)x=xx;y=yy;float GetX( )return x;float GetY( )return y;解決方案1將計算兩點距離的函數(shù)設計為類外的普通函數(shù)2022/9/1689float Distance(Point a , Point b)float x1,x2,y1,y2,dx,dy;x1=a.GetX(); y1=a.GetY();x2=b.GetX(); y2=b.GetY();dx=x

46、1-x2;dy=y1-y2;return sqrt(dx*dx+dy*dy);void main()Point p1(3.0, 5.0), Point p2(4.0, 6.0); float d=Distance(p1, p2); coutThe distance is ;coutdendl;/輸出: The distance is 1.1421這種方案的缺點:因為類外函數(shù)是不能直接訪問類中的私有成員的,因此該函數(shù)必須調(diào)用GetX和GetY公有成員函數(shù)先獲取“點”的坐標,然后再計算兩點距離,這種方式是不太方便的。另一種方案就是將計算兩點距離的函數(shù)設計成為Point類的成員函數(shù)。雖然從語法的角度

47、來看這不難實現(xiàn),但是理解起來卻有問題:距離反映的是兩點之間的關(guān)系,它既不屬于每一個單獨的點,也不屬于整個Point類。2022/9/1690解決方案2:設計為友元函數(shù)將一個函數(shù)聲明為一個類的友元函數(shù)時,該函數(shù)就具有以下特點:該類函數(shù)可以直接訪問私有成員。友元函數(shù)不屬于任何類,因此友元函數(shù)沒有this指針。友元函數(shù)訪問非靜態(tài)成員的方式與靜態(tài)成員函數(shù)是一樣的。友元函數(shù)的聲明可以放在類內(nèi)的任何位置。和普通函數(shù)一樣,可直接調(diào)用友元函數(shù)。2022/9/16912022/9/1692float Distance(Point a , Point b)float dx,dy;dx=a.x-b.x;dy=a.y

48、-b.y;return sqrt(dx*dx+dy*dy);void main()Point p1(3.0, 5.0);Point p2(4.0, 6.0); float d=Distance(p1, p2); coutThe distance is ;coutdendl;/輸出: The distance is 1.1421class Pointfriend float Distance(Point a, Point b);友元類除了將一個普通函數(shù)聲明為一個類的友元函數(shù)外,也可以將一個類Y聲明為另一個類X的友元類,那么,類Y中的所有成員函數(shù)都成為類X的友元函數(shù),都能直接訪問類X中所有的成員。

49、2022/9/1693舉例2022/9/1694class Y;/向前說明class Xint x;friend class Y;public:void show()coutx;class Y public:void SetX( X &obj,int v)obj.x=v;void main()X xobj;Y yobj;yobj.SetX(xobj,5);xobj.show();/輸出:5將成員函數(shù)說明為另一個類的友元函數(shù)2022/9/1695class X;/向前說明class Y public:void SetX( X &obj,int v);void func(X &obj );class Xfriend void Y:SetX( X &obj,int v);void Y:SetX( X &obj,int v)obj.x=v;對友元關(guān)系的總結(jié)友元具有如下的性質(zhì):類的友元可以直接訪問它的所有成員。友元的聲明必須放在類的內(nèi)部,但放在哪個段沒有區(qū)別。友元關(guān)系不具備對稱性,即X

溫馨提示

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

評論

0/150

提交評論