




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、C+程序設計第第5講講 關于類和對象的進一步討論關于類和對象的進一步討論重點:重點:對象數組、對象指針、對象數組、對象指針、共用數據的保護、對象的動態建立和釋放共用數據的保護、對象的動態建立和釋放關于類和對象的進一步討論1. 1. 構造函數構造函數2. 2. 析構函數析構函數3. 3. 調用構造函數和析構函數的順序調用構造函數和析構函數的順序4. 4. 對象數組對象數組5. 5. 對象指針對象指針6. 6. 共用數據的保護共用數據的保護7. 7. 對象的動態建立和釋放對象的動態建立和釋放8. 8. 對象的賦值和復制對象的賦值和復制9. 9. 靜態成員靜態成員10. 10. 友元友元11. 11
2、. 類模板類模板 定義格式定義格式 *=; 賦值方法賦值方法=& 1.2 指向對象成員的指針指向對象成員的指針(1) 指向類的數據成員的指針指向類的數據成員的指針class Aclass A public: public: int int fun(int fun(int b) b)return areturn a* *c+b;c+b;A(intA(int i) i)a=i;a=i;intint c; c;private:private: int int a; a;例如:定義一個指向類例如:定義一個指向類A的數據成員的數據成員c的指針的指針pc,其格式如下:,其格式如下: int A *
3、pc=&A c;或:或: int A *pc pc=&A:c;1.2 指向對象成員的指針指向對象成員的指針(1) 指向類的數據成員的指針指向類的數據成員的指針 引用方法引用方法使用類的對象引用時:使用類的對象引用時: .*使用對象指針引用時:使用對象指針引用時: -* 1.2 指向對象成員的指針指向對象成員的指針(1) 指向類的數據成員的指針指向類的數據成員的指針n使用類使用類A對象給對象給pc所指向的數據成員所指向的數據成員c賦值,其格式賦值,其格式如下:如下:A a;a.*pc=10;n使用指向類使用指向類A對象指針對象指針p給給pc所指向的數據成員所指向的數據成員c賦賦值
4、,其格式如下:值,其格式如下:A a;A *p=&a;p-*pc=10; int A *pc=&A c; 或:或: int A *pc pc=&A:c;(2) (2) 指向類的成員函數的指針指向類的成員函數的指針 定義格式定義格式 ( ( * * )()( ) ); ; 賦值方法賦值方法指向函數的指針名指向函數的指針名= =類名類名函數名;函數名; 引用方法引用方法使用類的對象引用時,使用類的對象引用時,( (對象名對象名* *指向成員函數的指針名指向成員函數的指針名)()(參數表參數表) );使用類的對象指針引用時,使用類的對象指針引用時,( ( -* * )()(
5、) );定義一個指向成員函數定義一個指向成員函數fun( )的指針的指針pfun如下:如下:int(A *pfun) (int);給指向成員函數的指針給指向成員函數的指針pfun賦值如下:賦值如下:pfun=A fun; 注:注:fun的賦值方式的賦值方式通過通過pfun調用它所指向的成員函數的格調用它所指向的成員函數的格式如下:式如下:A a;(a.*pfun) (5);使用指向類使用指向類A對象的指針通過對象的指針通過pfun調用它調用它所指向的成員函數的格式如下:所指向的成員函數的格式如下:A a;A *p=&a(p-*pfun) (5); class A public:int
6、fun(int b) return a*c+b; A(int i) a=i;int c;private:int a; ;例例:void main() A x(8);int A:*pc; /定義指向類定義指向類A的數據成員的指針的數據成員的指針Pc=&A:c;x.*pc=3;int(A:*pfun)(int); /定義指向類定義指向類A的成員函數的指針的成員函數的指針pfun=A:fun;A *p=&x;cout*pfun)(5)endl;n是隱含于每一個類的成員函數中的特殊指針(包括構造函數和是隱含于每一個類的成員函數中的特殊指針(包括構造函數和析構函數);析構函數);n用于指
7、向正在被成員函數操作的對象;用于指向正在被成員函數操作的對象;當通過一個對象調用成當通過一個對象調用成員函數時,系統先將該對象的地址賦給員函數時,系統先將該對象的地址賦給this指針,然后調用成指針,然后調用成員函數員函數,成員函數對對象的數據成員進行操作時,就隱含使用,成員函數對對象的數據成員進行操作時,就隱含使用了了this指針;指針;n*this標識調用該成員函數的對象標識調用該成員函數的對象;(;(this是一個指針變量,一是一個指針變量,一般不直接用來引用對象成員)般不直接用來引用對象成員)n類型:類名類型:類名*const thisn該指針是由系統自動產生的,不需要人為定義出;并且
8、它是常該指針是由系統自動產生的,不需要人為定義出;并且它是常量指針,不能被賦值,只能使用它。量指針,不能被賦值,只能使用它。表示是一個常量指針表示是一個常量指針1.3 this指針例:分析下列程序的輸出結果。例:分析下列程序的輸出結果。#include class Apublic: A( ) a=b=0; A(int i,int j) a=i;b=j; void copy(A &aa); void print() couta, bendl;private: int a,b; void A:copy(A &aa) if(this=&aa) return; *this=aa
9、; void main() A a1,a2(3,4); a1.copy(a2); a1.print();輸出:輸出:3,4系統將對象系統將對象a1的地址賦給的地址賦給this*this是對象是對象a1例:顯式使用例:顯式使用this指針訪問數據成員指針訪問數據成員編寫一個類編寫一個類ThisPointer,通過顯式使用,通過顯式使用this指針訪問指針訪問數據成員數據成員#include class ThisPointer int x; public: ThisPointer(int =0); /帶默認形參的構造函數帶默認形參的構造函數 void Disp();ThisPointer:This
10、Pointer(int value) x=value;void ThisPointer:Disp() cout“ x=“x; /隱式使用隱式使用this指針指針 coutx=“x; /顯式使用顯式使用this指針指針 cout“n(*this).x=“(*this).xendl; /顯式使用顯式使用this指針指針 int main() ThisPointer ThisObject(10);ThisObject.Disp(); return 0;例程序:例程序: #include class Sample int n; public: Sample( ) Sample (int m) n=m;
11、 Sample add(Sample s1,Sample s2) this-n=s1.n+s2.n; return (*this); void disp( ) cout“n=“nendl; ; void main( ) Sample s1(10),s2(5),s3,s4; cout“s1:”; s1.disp( ); cout“s2:”; s2.disp( ); s4=s3.add(s1,s2); cout“s3:”; s3.disp( ); cout“s4:”; s4.disp( );注意注意:在靜態成員函數中沒有在靜態成員函數中沒有this指針。因為它指針。因為它是同類的所有對象共享的資源
12、,只有一個是同類的所有對象共享的資源,只有一個共用的副本。共用的副本。對象引用的定義和賦值對象引用的定義和賦值定義定義ra是是類類A的一個對象的一個對象a的引用,其說明格式如的引用,其說明格式如下:下:A a; A &raA a; A &ra=a;=a;l 對象引用可作函數參數及返回值對象引用可作函數參數及返回值三、三、 對象引用對象引用例:對象引用作函數參數例:對象引用作函數參數#include class Mpublic: M( ) x=y=0; M(int i,int j) x=i;y=j; void copy(M &m); /m為引用為引用 void setxy
13、(int i,int j) x=i;y=j; void print() coutx, yendl;private: int x,y;例:對象引用作函數參數例:對象引用作函數參數void M:copy(M &m) x=m.x; y=m.y;void fun(M m1,M &m2); void main() M p(5,7),q; q.copy(p); fun(p,q); p.print(); q.print();void fun(M m1,M *m2)fun(p,&q);void fun(M m1,M &m2) m1.setxy(12,15); m2.setxy(
14、22,25);輸輸出出5,722,252、對象引用作函數參數、對象引用作函數參數n該方法除了具有對象指針作函數參數的該方法除了具有對象指針作函數參數的優點優點外,還更簡單更直接,應用更廣;外,還更簡單更直接,應用更廣;三、共用數據的保護n常類型:使用類型修飾符常類型:使用類型修飾符const說明的類型;說明的類型;n常類型的變量或對象的值是不能被更新的;常類型的變量或對象的值是不能被更新的;n定義或說明常類型時必須初始化;定義或說明常類型時必須初始化; 1、一般常量(簡單類型的常量)、一般常量(簡單類型的常量) constconst 或或constconst int int const x=2
15、; const x=2; 或或const intconst int x=2; x=2;intint const a3=1,2,3; const a3=1,2,3; 或或 const intconst int a3=1,2,3; a3=1,2,3;數組元素的值是常量,不能更新;數組元素的值是常量,不能更新;2 2、常對象、常對象 const A const a1(3,4);A const a1(3,4);常對象a1三、 共用數據的保護 class A class A public:public: const A a1(3,4);const A a1(3,4); A(int i,int j)x=i
16、;y A(int i,int j)x=i;y=j;=j; private: private: int x,y int x,y; ; ; ;三、共用數據的保護n可以將對象的成員聲明為可以將對象的成員聲明為constconst,包括常數據成員和,包括常數據成員和常成員函數。常成員函數。n常數據成員的作用和用法與一般常變量相似,用關常數據成員的作用和用法與一般常變量相似,用關鍵字鍵字const來聲明常數據成員。常數據成員的值是不來聲明常數據成員。常數據成員的值是不能改變的。能改變的。3、常數據成員、常數據成員n常數據成員只能通過成員初始化列表的方法進行初常數據成員只能通過成員初始化列表的方法進行初始
17、化;始化; 例例6 6:分析下列程序的輸出結果。分析下列程序的輸出結果。#include iostream.h#include class Aclass A public:public: A(int A(int i); i); void Print(); void Print();private:private: const intconst int a; a; static const int static const int b; b; const int const int &r; &r;const intconst int A:b=10; A:b=10;A:A(intA
18、:A(int i i) :a(i),r(a):a(i),r(a) 私有私有成員,常引用成員,常引用r r私有成員,常量私有成員,常量a a私有常靜態數據成員私有常靜態數據成員b b成員初始化列表成員初始化列表,常成員常成員( (除常靜態成員外除常靜態成員外) )在此初始化在此初始化私有常靜態數據成員私有常靜態數據成員b b初始化初始化三、共用數據的保護void A:Print()void A:Print() couta:b:rendl couta:b:rendl; ; intint main() main() A a1(100),a2(0); A a1(100),a2(0); a1.Print
19、(); a1.Print(); a2.Print(); a2.Print(); return 0; return 0; 輸輸出出100:10:1000:10:0三、共用數據的保護三、 共用數據的保護(自學) 4、常成員函數常成員函數n使用使用constconst關鍵字進行說明的成員函數關鍵字進行說明的成員函數; ( ) const;) const;constconst是是函數類型的的一個組成組成部分,在函數實現部分,在函數實現部分必須帶有必須帶有constconst關鍵字關鍵字;說明:說明:n只有常成員函數才能操作常對象只有常成員函數才能操作常對象;表成員函數與對象之間的操作關系表成員函數與對
20、象之間的操作關系例:分析下列程序是否正確。例:分析下列程序是否正確。#include iostream.h#include class Mclass M public:public: M(int x,int M(int x,int y) X=x;Y=y; y) X=x;Y=y; void Move(int x,int void Move(int x,int y) X=x;Y=y; y) X=x;Y=y; void Print() const coutX, Yendl void Print() const coutX, Yendl;private:private: int int X,Y; X,
21、Y;一般成員函數一般成員函數常成員函數常成員函數三、共用數據的保護void main()void main() const M m1(1,2); const M m1(1,2); m1.Move(3,3); m1.Move(3,3); m1.Print(); m1.Print(); M m2(3,4); M m2(3,4); m2.Move(3,3); m2.Move(3,3); m2.Print(); m2.Print(); 常對象常對象m1m1一般對象一般對象m2m2錯誤錯誤,一般成員函數一般成員函數不能操作常對象不能操作常對象三、共用數據的保護三、共用數據的保護 5、常指針常指針char
22、 char * * const ptr1=strptr1; const ptr1=strptr1;ptr1ptr1是一個常量指針;是一個常量指針;ptr1=strptr2;ptr1=strptr2;* *ptr1=m;ptr1=m;ptr1ptr1不可以更新不可以更新ptr1ptr1所指向的變量可以更新;所指向的變量可以更新;constconst的位置的位置const char const char * * ptr2=strptr1; ptr2=strptr1;ptr2ptr2是一個指向字符串常量的指是一個指向字符串常量的指針;針;ptr2=strptr2;ptr2=strptr2;* *pt
23、r2=m;ptr2=m;ptr2ptr2可以更新可以更新ptr2ptr2所指向的字符串不可以更新;所指向的字符串不可以更新;錯誤正確正確錯誤n常引用所引用的對象不能被更新;常引用所引用的對象不能被更新;const const & & double x=1.2; const double & v=x;double x=1.2; const double & v=x;則:則:v=12.3v=12.3錯誤。錯誤。三、共用數據的保護n例例9.8 對象的常引用對象的常引用void fun(Timevoid fun(Time &t) &t) /形參形參t t
24、是是TimeTime類對象的引用類對象的引用 t.hour t.hour=18; =18; intint main( ) main( ) Time t1(10,13,56); Time t1(10,13,56); / t1/ t1是是TimeTime類對象類對象 fun(t1); fun(t1); /實參是實參是TimeTime類對象,可以通過引用來修改實參類對象,可以通過引用來修改實參t1t1的值的值 coutt1.hourendlcoutt1.hourendl; ; /輸出輸出t1.hourt1.hour的值為的值為1818 return 0; return 0; 三、共用數據的保護形式形
25、式含義含義Time const t1; t1是常對象,其值在任何情況下都不能改變是常對象,其值在任何情況下都不能改變void Time fun( )constfun是是Time類中的常成員函數,可以引用,類中的常成員函數,可以引用,但不能修改本類中的數據成員但不能修改本類中的數據成員Time * const p;p是指向是指向Time對象的常指針,對象的常指針,p的值的值(即即p的的指向指向)不能改變不能改變const Time *p;p是指向是指向Time類常對象的指針,其指向的類類常對象的指針,其指向的類對象的值不能通過指針來改變對象的值不能通過指針來改變Time &t1=t;t1
26、是是Time類對象類對象t的引用,二者指向同一段的引用,二者指向同一段內存空間內存空間表表9.3四、對象的動態建立和釋放 與在內存中動態創建與在內存中動態創建/ /撤銷變量一樣,也可以在內存中用撤銷變量一樣,也可以在內存中用newnew動態創建對象,并可隨時用動態創建對象,并可隨時用deletedelete釋放它。釋放它。int* p=new int(5);*p=200;delete p;例例13 Box* p;p=new Box(1,2,3);coutvolume();delete p; 需要注意的是,在動態創建對象時,也會調用構造函數。需要注意的是,在動態創建對象時,也會調用構造函數。在用
27、在用deletedelete釋放它時,也會調用析構函數。釋放它時,也會調用析構函數。例例14 Box* p=new Box10;coutp5.volume();delete p;堆對象堆對象例例15 分析程序的輸出結果分析程序的輸出結果5.1 5.1 對象的賦值對象的賦值五、對象的賦值和復制Box b1(1,2,3), b2;/定義兩個同類的對象定義兩個同類的對象b2=b1; /將將b1賦給賦給b2 對象賦值一般形式為對象賦值一般形式為: :對象名對象名1 = 1 = 對象名對象名2;2;注意:對象名注意:對象名1 1和對象名和對象名2 2必須屬于同一個類。必須屬于同一個類。例例16 分析程序
28、的輸出結果(分析程序的輸出結果(P292例例9.9)幾點說明:幾點說明: (1)(1)對象賦值只對其中的數據成員賦值,而不對成員函數賦值對象賦值只對其中的數據成員賦值,而不對成員函數賦值(2)(2)類的數據成員中不能包括動態分配的數據,否則在賦值時類的數據成員中不能包括動態分配的數據,否則在賦值時可能出現嚴重后果。可能出現嚴重后果。5.2 對象的復制 對象的賦值是兩個已存在的對象間的操作,而對象的復制對象的賦值是兩個已存在的對象間的操作,而對象的復制則是根據一個已有對象創建一個新的相同的對象(克隆)。則是根據一個已有對象創建一個新的相同的對象(克隆)。 對象的復制是借助于對象的復制是借助于復制
29、構造函數復制構造函數來完成的來完成的。1 1、復制構造函數的功能、復制構造函數的功能 用一個已知的對象來初始化一個被創建的同類對象。用一個已知的對象來初始化一個被創建的同類對象。2 2、復制構造函數的特點、復制構造函數的特點n函數名同類名,無返回類型;函數名同類名,無返回類型;n只有一個參數,是對某個對象的引用只有一個參數,是對某個對象的引用類名類名(類名類名& 引用名引用名)n每個類必有一個復制(拷貝)構造函數每個類必有一個復制(拷貝)構造函數n如果類中未提供拷貝初始化構造函數,則編譯器自動如果類中未提供拷貝初始化構造函數,則編譯器自動生成一個缺省拷貝初始化構造函數作為該類的公有成員
30、生成一個缺省拷貝初始化構造函數作為該類的公有成員例例17 分析程序的輸出結果分析程序的輸出結果5.2 對象的復制3 3、使用復制構造函數初始化的三種情況使用復制構造函數初始化的三種情況 明確表示由一個對象初始化另一個對象時明確表示由一個對象初始化另一個對象時TPoint M(1,2); TPoint N(M); 當對象作為實參傳遞給形參時當對象作為實參傳遞給形參時int main() TPoint M(1,2); fun(M); /實參實參M傳給形參傳給形參Q,調用拷貝構造函數,調用拷貝構造函數void fun(TPoint Q)5.2 對象的復制 當對象作為函數返回值時當對象作為函數返回值時
31、TPoint fun2()TPoint R(1,2);return R; /將將R對象作為返回值,調用拷貝構造函數對象作為返回值,調用拷貝構造函數int main() TPoint M(1,2), p(0,0); p=fun2(); 例例18 分析程序的輸出結果分析程序的輸出結果Copy Constructor called.Copy Constructor called.OK!Copy Constructor called.Destructor called.Destructor called.Destructor called.P=30, 55Destructor called.Destr
32、uctor called.Destructor called.5.2 對象的復制/TPointTPoint N(M) N(M)/調用調用f(Nf(N),),由實參由實參N N復制出形參復制出形參Q Q/return R,return R,由對象由對象R R復制出匿名對象復制出匿名對象/執行執行R R的析構函數的析構函數/執行執行Q Q的析構函數的析構函數/執行執行匿名對象匿名對象的析構函數的析構函數/執行執行N N的析構函數的析構函數/執行執行P P的析構函數的析構函數/執行執行M M的析構函數的析構函數9.9 靜態成員 一般地說,若創建某一般地說,若創建某類的類的多個多個對象,對象,這些這些
33、對象各有其值,對象各有其值,彼此互不相干。彼此互不相干。 但是,有時同類的對象之間需要共享一些數據但是,有時同類的對象之間需要共享一些數據,這些數據,這些數據為所有對象共有(比如相鄰學校圖書館共享)為所有對象共有(比如相鄰學校圖書館共享)。 為了解決為了解決同類同類對象對象之之間的數據共享問題,間的數據共享問題,C+C+引入了靜態引入了靜態成員。成員。 靜態成員分為靜態成員分為靜態數據成員靜態數據成員和和靜態成員函數靜態成員函數。101517382677abc9.9.1 靜態數據成員 在類體中某數據成員的聲明前加上在類體中某數據成員的聲明前加上staticstatic,該成員就成為,該成員就成
34、為 靜態數據成員。靜態數據成員。 靜態數據成員具有以下特點:靜態數據成員具有以下特點:class Mpublic: static char x;private: int z; static int y;x x為公有的靜態數據成員為公有的靜態數據成員靜態數據成員由本類的所有對象共有,靜態數據成員由本類的所有對象共有,它它不專屬于某個對象,不專屬于某個對象,而是屬于整個類。而是屬于整個類。因此,可以使用類名引用它,格式為:因此,可以使用類名引用它,格式為:類名類名:靜態數據成員名靜態數據成員名在為對象分配的空間中,不包括在為對象分配的空間中,不包括靜態數靜態數據成員所占空間。它被存放在一個據成員所
35、占空間。它被存放在一個單獨單獨的的存儲單元中,供所有對象使用,它的值對存儲單元中,供所有對象使用,它的值對所有對象都是一樣的。若某對象改變了它的值,則所有對象該所有對象都是一樣的。若某對象改變了它的值,則所有對象該成員的值都同時改變。成員的值都同時改變。y y為私有的靜態數據成員為私有的靜態數據成員9.9.1 靜態數據成員class Mpublic: static char x;private: int z; static int y;靜態數據成員采用靜態存儲方式,其生存期長。靜態數據成員采用靜態存儲方式,其生存期長。靜態數據成員必須初始化后方可使用,靜態數據成員必須初始化后方可使用,與一般數
36、據成員初始化不同與一般數據成員初始化不同,它在類體外,它在類體外按如下按如下格式初始化:格式初始化:數據類型數據類型 類名類名:靜態數據成員名靜態數據成員名= =初值初值; ;注意:前面沒有注意:前面沒有staticstatic程序開始執行時分配空間,一直占用程序開始執行時分配空間,一直占用至程序結束至程序結束與是否已定義對象無關與是否已定義對象無關char M:x=W;int M:y=10;例例19 引用靜態數據成員(引用靜態數據成員(P297例例9.10)9.9.1 靜態數據成員#include using namespace std;class Boxpublic: Box(int,in
37、t); int volume( ); int length; int width; static int height; ;int Box:height=10; Box:Box(int l,int w) length=l; width=w; 把把heightheight定義為公用的定義為公用的靜態數據成員靜態數據成員在類體外對靜態數據成員在類體外對靜態數據成員heightheight初始化初始化通過構造函數對數據成員通過構造函數對數據成員lengthlength、widthwidth賦初值賦初值int Box:volume( ) return length*width*height;int m
38、ain( ) Box a(15,20),b(20,30); couta.heightendl; coutb.heightendl; coutBox:heightendl; couta.volume( )endl; return 0;通過對象名通過對象名a a引用靜態引用靜態 數據成員數據成員通過對象名通過對象名b b引用靜態引用靜態 數據成員數據成員通過類名引用靜態數據通過類名引用靜態數據成員成員調用對象調用對象a a的的volumevolume函數函數計算體積并輸出結果計算體積并輸出結果9.9.2 靜態成員函數class Mpublic: static int fun(); static c
39、har x;private: int z; static int y;int M:fun() 靜態成員函數有兩種引用形式:靜態成員函數有兩種引用形式: 成員函數也可以成員函數也可以聲明聲明為靜態的,只需在函數聲明前加上為靜態的,只需在函數聲明前加上staticstatic就成了靜態成員函數。定義靜態成員函數的就成了靜態成員函數。定義靜態成員函數的目的目的是為了是為了處理類中的靜態數據成員。處理類中的靜態數據成員。 對象名對象名.靜態成員函數名靜態成員函數名(實參列表實參列表) 類名類名:靜態成員函數名靜態成員函數名(實參列表實參列表)int main()M a;a.fun();M:fun();
40、例例20 靜態成員函數的應用靜態成員函數的應用9.9.1 靜態數據成員class Studentpublic: Student(int n, int s) num=n; score=s; count+; void total() sum+=score; static double aver();private: int num, score; static int sum, count;int Student:sum=0;int Student:count=0;有兩個私有有兩個私有數據成員數據成員numnum、countcount在類體外在類體外對靜態數據成員對靜態數據成員sumsum、cou
41、ntcount初始化初始化通過構造函數對數據成員通過構造函數對數據成員numnum、scorescore初始化初始化有兩個私有靜態有兩個私有靜態數據成員數據成員s sumum、countcount每創建一個對象每創建一個對象countcount增增1 1累加對象的累加對象的scorescore至至sumsum計算所有對象的平均分計算所有對象的平均分double Student:aver() return double(sum)/count;int main() Student s3= Student(1001,80), Student(1002,90), Student(1003,100) ;
42、 for(int i=0; i3; i+) si.total(); coutStudent:aver(); return 0;定義靜態成員函數定義靜態成員函數訪問靜態數據成員訪問靜態數據成員sum、count定義對象數組,并初始化定義對象數組,并初始化調用調用對象對象si的的total函數函數使用使用Student:aver()調用靜態成員函數調用靜態成員函數與一般的成員函數不同,靜態成員函數沒有與一般的成員函數不同,靜態成員函數沒有this指針。因此指針。因此在靜態成員函數的定義中,雖然可直接引用靜態數據成員,在靜態成員函數的定義中,雖然可直接引用靜態數據成員,但不能直接引用非靜態數據成員。
43、但不能直接引用非靜態數據成員。9.9.2 靜態成員函數 關于靜態成員函數的幾點說明:關于靜態成員函數的幾點說明:在在靜態成員函數的靜態成員函數的定義中,定義中,如果一定如果一定要引用非靜態成員,應要引用非靜態成員,應該通過該通過 對象名對象名.數據成員名數據成員名 來引用。來引用。class Mpublic: static int fun(); static char a;private: int b; static int c;int M:fun() c=15; b=20; 例例21 在上例基礎上,演示靜態成員函數如何訪問一個對象的在上例基礎上,演示靜態成員函數如何訪問一個對象的一般數據成員
44、一般數據成員例例22 分析程序的輸出結果分析程序的輸出結果9.10 友元 友元即朋友(友元即朋友(friend),一個類的友元雖不是類的成員,),一個類的友元雖不是類的成員,但可訪問該類中的所有成員。但可訪問該類中的所有成員。class Apublic: void f1(); private: int a; ;類類A的友元的友元友元函數友元函數友元類友元類普通函數普通函數其它類的其它類的成員函數成員函數1 1、將普通函數聲明為友元函數、將普通函數聲明為友元函數 只需在類只需在類A體中用體中用friend對對函數加以聲明即可。函數加以聲明即可。void f2(int k) A v; coutv.
45、aendl; friend void f2(int k);在在f2f2中可引用中可引用A A類對象類對象v v的的私有成員私有成員例例23 友元函數的簡單例子友元函數的簡單例子 (P302例例9.12)9.9.1 靜態數據成員class Timepublic: Time(int,int,int); friend void display(Time &); private: int hour, minute, sec;Time:Time(int h,int m,int s) hour=h; minute=m; sec=s;void display(Time& t) coutt.h
46、our: t.minute: t.secendl;定義定義普通普通函數函數displaydisplay,其中形參其中形參為為TimeTime類對象的類對象的引用引用,需要,需要訪問訪問TimeTime中的中的私有成員私有成員聲明聲明displaydisplay函數為函數為TimeTime類的友元函數類的友元函數定義定義TimeTime類類int main( ) Time t1(10,13,56); display(t1); return 0; 創建對象創建對象t1t1調用調用displaydisplay函數,函數,實參為實參為TimeTime類對象類對象t1t1TimeTime類有類有3 3個
47、私有成員個私有成員9.10 友元 也可以將其它類的成員函數也可以將其它類的成員函數 聲明為類聲明為類A的友元函數。的友元函數。2 2、友元成員函數、友元成員函數class Bpublic: void f2(A& v); ;class Apublic: void f1(); private: int a; ;void B:f2(A& v) coutv.aendl; friend void B:f2(A&);在在f2中可訪問中可訪問A類對象類對象v的的私有成員私有成員 但是,這種方案還有點問題。但是,這種方案還有點問題。解決方法解決方法:對:對A進行進行提前引用聲明提前引用
48、聲明,告訴編譯器告訴編譯器A是個類,定義在后面是個類,定義在后面.class A; /提前引用聲明提前引用聲明我們知道,編譯器是自上而下進行我們知道,編譯器是自上而下進行編譯的,當遇到編譯的,當遇到void f2(A& v);時,由于類時,由于類A定義在后,編譯器并定義在后,編譯器并不知道不知道A是什么,于是報錯。是什么,于是報錯。例例24 友元成員函數的簡單應用友元成員函數的簡單應用(P303例例9.13)9.9.1 靜態數據成員class Date;class Time public: Time(int, int, int); void display(Date &);pr
49、ivate: int hour, minute, sec;class Datepublic: Date(int,int,int); friend void Time:display(Date&); private: int year, month, day;對對DateDate類的提前引用聲明類的提前引用聲明定義定義TimeTime類類聲明聲明displaydisplay函數,其形參為函數,其形參為DateDate類對象的引用類對象的引用定義定義DateDate類類聲明聲明TimeTime類的類的displaydisplay函數為函數為DateDate類的友元函數類的友元函數9.9.1
50、 靜態數據成員Time:Time(int h,int m,int s) hour=h; minute=m; sec=s;void Time:display(Date &d) coutd.year/d.month/d.dayendl; couthour:minute:secy?x:y; int min() return xy?x:y; float min() return xy?x:y; T min() return xy?x:y; private: T x, y;顯然,當顯然,當T T取不同的數據類型時,就得到各個具體的類取不同的數據類型時,就得到各個具體的類9.11 類模版 類模版的
51、定義格式為:類模版的定義格式為:template class 類模版名類模版名;template class cmppublic: cmp(T a,T b) x=a; y=b; T max() return xy?x:y; T min() return xy?x:y; private: T x, y; 在定義類模版后,按照以下格式在定義類模版后,按照以下格式可得到具體的類(稱為可得到具體的類(稱為模版類模版類):):類模版名類模版名 cmp cmp cmp 用于int數據比較的類用于float數據比較的類用于string數據比較的類class cmppublic: cmp(int a,int
52、b) x=a; y=b; int max() return xy?x:y; int min() return xy?x:y; private: int x, y;class cmppublic: cmp(float a,float b) x=a; y=b; float max() return xy?x:y; float min() return xy?x:y; private: float x, y;class cmppublic: cmp(string a,string b) x=a; y=b; string max() return xy?x:y; string min() return
53、 xy?x:y; private: string x, y;9.11 類模版 進一步地,還可以用這些模版類來定義對象。進一步地,還可以用這些模版類來定義對象。template class cmppublic: cmp(T a,T b) x=a; y=b; T max() return xy?x:y; T min() return xy?x:y; private: T x, y;cmp cmp cmp a(10,20);b(10.1,20.2);c(”Li”,”Wang”);couta.max()endl; coutb.min()endl;coutc.max()endl;9.11 類模版 總之,
54、在定義類模版后,可以用總之,在定義類模版后,可以用類模版名類模版名 對象名對象名(初值初值1,初值,初值m);來定義對象,例如來定義對象,例如cmp a(10,20);建立對象建立對象a a的具體過程如下:的具體過程如下:template class cmppublic: cmp(T a,T b) x=a; y=b; T max() return xy?x:y; T min() return xy?x:y; private: T x, y;告訴編譯器從模板告訴編譯器從模板cmp產生產生一個名為一個名為cmp的類,模板中的的類,模板中的所有參數所有參數T均用均用int替換;替換;創建對象創建對象
55、a,并把初值,并把初值10、20傳遞傳遞給構造函數,以初始化該對象的數據給構造函數,以初始化該對象的數據成員。成員。例例25 聲明一個類模板,利用它分別聲明一個類模板,利用它分別實現兩個整數、浮點數和字符的比較實現兩個整數、浮點數和字符的比較求出大數和小數。求出大數和小數。(P308例例9.14)class cmppublic: cmp(int a,int b) x=a; y=b; int max() return xy?x:y; int min() return xy?x:y; private: int x, y;補充:關于程序結構 到目前為止,我們的程序存放在一個文件中,并且具有如到目前為
56、止,我們的程序存放在一個文件中,并且具有如下結構。下結構。class A/類的聲明部分類的聲明部分;A:fun()/類的實現部分類的實現部分int main()/主函數及其他函數主函數及其他函數A.hA.cppfile.cpp補充:關于程序結構 這樣一來,程序就由多個文件這樣一來,程序就由多個文件A.h、A.cpp、file.cpp組成組成并需作如下調整。并需作如下調整。#include ”a.h”A:fun()/類的實現部分類的實現部分A.cppfile.cpp#include ”a.h”int main()/主函數及其他函數主函數及其他函數補充:關于程序結構 通常,人們會把相關的一些類的實
57、現文件(如通常,人們會把相關的一些類的實現文件(如A.cpp等)等)編譯,并將結果目標文件組裝成一個文件,該文件即為編譯,并將結果目標文件組裝成一個文件,該文件即為類庫類庫。利用類庫,可保護自己的知識產權利用類庫,可保護自己的知識產權 當然,在把類庫提供給他人的時候,還應提供相應類聲明當然,在把類庫提供給他人的時候,還應提供相應類聲明文件即頭文件(如文件即頭文件(如A.h)。)。C+程序設計第第9章章 關于類和對象的進一步討論關于類和對象的進一步討論課后作業與上機練習題目課后作業與上機練習題目本章作業1.1.分析下列程序的輸出結果分析下列程序的輸出結果(1 )#includeusing nam
58、espace std;class Sample int x,y;public: Sample() x=y=0; Sample(int a,int b) x=a;y=b; Sample()if(x=y)coutx=yendl; else coutx!=yendl; void disp() coutx=x,y=yendl; ;int main()Sample s1,s2(2,3); s1.disp(); s2.disp();本章作業(2)#include using namespace std;class Myclasspublic: Myclass(int a,int b,int c); voi
59、d GetNumber(); void GetSum();private: int A,B,C; static int Sum;int Myclass:Sum=0;Myclass:Myclass(int a,int b,int c) A=a; B=b; C=c; Sum+=A+B+C;void Myclass:GetNumber() coutNumber=A, B, Cendl;void Myclass:GetSum() coutSum=Sumendl;int main() Myclass M(3,7,10),N(14,9,11); M.GetNumber(); N.GetNumber();
60、M.GetSum(); N.GetSum(); return 0;本章作業(3#includeusing namespace std;class Spublic:S(int a,int b):x(a),y(b) cout含初始化表的構造函數含初始化表的構造函數endl;S(S& t) x=t.x;y=t.y;cout復制構造函數復制構造函數endl;S(int a=0) x=a; y=10;cout帶默認參數的構造函數帶默認參數的構造函數endl;void disp();private:int x,y;void S:disp()coutx, yendl;int main()S s1(1),s2;S s3(20,30),s4(s1);s1.disp();s2.disp();s3.disp();s4.disp();return 0;本章作業(4)#includeusing namespace std;class Point int x, y;public: Point(int a
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 從終端反饋看醫療供應鏈優化方向
- AI技術助力醫療大數據分析提升健康管理水平
- 辦公自動化與區塊鏈的供應鏈管理
- 計算機課程序設計基礎
- 從單一到多元探索多維度下基于區塊鏈的版權保護策略
- 環藝畢業設計家具創新與實踐
- 幼兒園關于風的班本課程:探索風的奇妙世界
- 2024年山東萊蕪公開招聘社區工作者考試試題答案解析
- 能見度儀企業ESG實踐與創新戰略研究報告
- 用于光盤精密注塑機企業數字化轉型與智慧升級戰略研究報告
- 化學計量學與化學分析技術考核試卷
- 2024關于深化產業工人隊伍建設改革的建議全文解讀課件
- 探究膜分離技術在水處理中的應用
- 洋流課件2024-2025學年高中地理人教版(2019)選擇性必修一
- 2024-2025學年中職數學拓展模塊一 (下冊)高教版(2021·十四五)教學設計合集
- 電梯維保工程施工組織設計方案
- 2024-2030年中國消防行業市場發展分析及發展趨勢與投資前景研究報告
- 外研版(2019) 必修第三冊 Unit 2 Making a Difference教案
- 醫院科研成果及知識產權管理規范
- DB32T-公路橋梁水下結構檢測評定標準
- 高職藥學專業《藥物制劑技術》說課課件
評論
0/150
提交評論