《C++實用教程[鄭阿奇主編]》由會員分享,可在線閱讀,更多相關《C++實用教程[鄭阿奇主編](35頁珍藏版)》請在裝配圖網上搜索。
1、第10章 類 和 對 象10.1 類和對象概述 n10.1.1 從結構到類n 例例Ex_StructToClass 從結構到類的示例。從結構到類的示例。n#include nusing namespace std;nstruct STUSCORE nncharstrName12;/姓名ncharstrStuNO9;/學號nfloatfScore3;/三門課程成績n;nfloat GetAverage(STUSCORE one)/計算平均成績nnreturn(float)(one.fScore0+one.fScore1+one.fScore2)/3.0);nnint main()nnSTUSCO
2、RE one=LiMing,21020501,80,90,65;ncoutone.strName 的平均成績?yōu)椋篏etAverage(one)n;nreturn 0;nn程序運行結果如下:LiMing的平均成績?yōu)椋?8.333310.1.2 類的聲明n1.類聲明的格式nC+中,聲明類的一般格式如下:nclass /聲明部分nnprivate:nnpublic:nnprotected:nn;n/實現部分n成員函數的定義格式如下:n :()nnn例Ex_StuScoreClass 一個類的定義示例。n#include nusing namespace std;nclass CStuscore nn
3、public:nfloat Average(void);/求平均成績:在類中聲明nchar*getName()/獲取姓名:聲明和定義同時在類中完成nnreturn strName;nnchar*getNo()/獲取學號:聲明和定義同時在類中完成nnreturn strStuNO;nnprivate:ncharstrName12;/姓名ncharstrStuNO9;/學號nprivate:nfloatfScore3;/三門課程成績n;nfloat CStuscore:Average(void)/在類體外部定義nnreturn(float)(fScore0+fScore1+fScore2)/3.0
4、);nnint main()nnreturn 0;nn2.幾點說明n1)類中數據成員的數據類型可以是任意的,如整型、浮點型、字符型、數組、指針和引用等,也可以是另一個類的對象。n2)由于類是一種數據類型,系統(tǒng)并不會為其分配內存空間,所以在定義類的數據成員時,不能對其初始化,也不能指定除static之外的任何存儲類型。n(3)訪問權限關鍵詞public、private、protected在類中使用時先后次序無關緊要,且可使用多次。每個訪問權限關鍵詞為類成員所確定的訪問權限是從該關鍵詞開始到下一個關鍵詞為止。n(4)在進行類設計時,通常將數據成員聲明為私有的,而將大多數成員函數聲明為公有的。n5)
5、一般來說,程序員更多關心公有成員,因此常將公有成員寫在類體的前面,而將私有成員寫在類體的后面。n(6)當程序比較大時,應盡量將類單獨存放在一個文件中或將類的聲明放在頭文件中,而將成員函數的實現放在與頭文件同名的.cpp文件中。n3.類和結構的區(qū)別10.1.3 對象的定義和成員的訪問n1.對象的定義方式n并按下列格式定義:n ;n2.對象成員的訪問 n.n.()n若對象是一個指針,則對象的成員訪問形式如下:n-n-()n下面的兩種表示是等價的:n-n(*).10.1.4 類作用域和成員訪問權限n1.類名的作用域n下列格式在使用前提前聲明:nclass;n2.類中成員的可見性n3.在類外對象成員的
6、可見性n4.在類中對象成員的可見性例例Ex_Class 一個類和對象使用的示例。一個類和對象使用的示例。n#include n#include nusing namespace std;nclass CStuscore nnpublic:nfloat Average(void);nvoid Print(void)ncout姓名:strNameendl;ncout學號:strStuNOendl;ncout課程成績:fScore0tfScore1tfScore2endl;ncout平均成績:aveendl;nnvoid Print(CStuscore one)ncout姓名:one.strName
7、endl;ncout學號:one.strStuNOendl;ncout課程成績:one.fScore0tone.fScore1tone.fScore2endl;ncout平均成績:one.aveendl;nnvoid setName(char*str)/設置姓名nstrncpy(strName,str,11);/最多拷貝11個字符nnvoid setNo(char*str)/設置學號nnstrncpy(strStuNO,str,9);/最多拷貝9個字符nnvoid setScore(float s1,float s2,float s3)/設置成績nnfScore0=s1;fScore1=s2;
8、fScore2=s3;nnprivate:ncharstrName12;/姓名ncharstrStuNO9;/學號nprivate:nfloatfScore3;/三門課程成績nfloat ave;/平均成績n;nfloat CStuscore:Average()/計算平均成績nnave=(float)(fScore0+fScore1+fScore2)/3.0);nreturn ave;nnint main()nnCStuscore one;none.setName(DING);none.setNo(21010301);none.setScore(90,80,78);none.Average()
9、;none.Print(one);nreturn 0;nn程序運行結果如下:10.2 構造函數和析構函數 n10.2.1 構造函數 n1.對象的初始化過程n2.構造函數n例Ex_Constructor 設計類的構造函數示例。n#include nusing namespace std;nclass CPersonnnpublic:nCPerson(char*str,float h,float w)/A:構造函數nnstrcpy(name,str);height=h;weight=w;n nCPerson(char*str)/B:構造函數nnstrcpy(name,str);nnCPerson(
10、float h,float w=120);/C:構造函數npublic:nvoid print()nncout姓名:namet身高:heightt體重:weightendl;nnprivate:nchar name20;/姓名nfloat height;/身高nfloat weight;/體重n;nCPerson:CPerson(float h,float w)nnheight=h;weight=w;nnint main()nnCPerson one(DING);none.print();nCPerson two(170,130);ntwo.print();nCPerson three(DIN
11、G,170,130);nthree.print();nreturn 0;nn程序運行結果如下:10.2.2 析構函數n其格式如下:n ()n n10.2.3 new和delete10.3 對象的使用10.3.1 對象賦值和拷貝n1.對象賦值nC+還常用下列形式的初始化來將另一個對象作為對象的初值:n()n2.分析和比較nCName的數據成員strName是一個“char*”指針,由于其自身的內存空間存放的是指針的地址,因而其數據的存儲還需另辟一個不依附外部的獨立的內存空間。n解決CName對象初始化中的內容拷貝問題,在C+中有兩種手段,一是給“=”運算符賦予新的操作,稱為運算符重載(以后會討論
12、);二是重新定義或重載默認拷貝構造函數。10.3.2 淺拷貝和深拷貝n1.淺拷貝n2.深拷貝n3.拷貝構造函數的格式n拷貝構造函數是一種特殊的構造函數,除遵循構造函數的聲明和實現規(guī)則外,還應按下列格式定義:(參數表)例Ex_CopyCon 使用拷貝構造函數示例。n#include n#include nusing namespace std;nclass CNamennpublic:nCName()nnstrName=NULL;nnCName(char*str)nnstrName=(char*)new charstrlen(str)+1;nstrcpy(strName,str);/拷貝內容n
13、nCName(CName&one)/A:顯式的默認拷貝構造函數n/為strName開辟獨立的內存空間nstrName=(char*)new charstrlen(one.strName)+1;nstrcpy(strName,one.strName);/拷貝內容nnCName(CName&one,char*add)/B:帶其他參數的拷貝構造函數n/為strName開辟獨立的內存空間nstrName=(char*)new charstrlen(one.strName)+strlen(add)+1;nstrcpy(strName,one.strName);/拷貝內容nstrcat(strName,a
14、dd);/連接到strName中nnCName()nnif(strName)delete strName;nstrName=NULL;/一個好習慣nnchar*getName()nnreturn strName;nnprivate:nchar*strName;/字符指針,名稱n;nint main()nnCName o1(DING);/通過構造函數初始化nCName o2(o1);/通過顯式的默認拷貝構造函數來初始化ncouto2.getName()endl;nCName o3(o1,YOU HE);/通過帶其他參數的拷貝構造函數來初始化ncouto3.getName()endl;nretur
15、n 0;nn程序運行結果如下:n4.對象作為函數的參數和返回值10.3.3 對象成員的初始化n如下列格式:n:(形參表):對象1(參數表),對象2(參數表),對象n(參數表)n n1.分析和比較n類的對象成員的初始化可以有兩種方式:n第1種方式(函數構造方式)n第2種方式(對象成員列表方式)例Ex_InitMultiObject 對象成員的初始化示例 n#include nusing namespace std;nclass CPoint nnpublic:nCPoint(int x=0,int y=0)n nnPosX=x;nPosY=y;nif(0=x)&(0=y)ncoutCPoint默
16、認構造函數endl;nelsencoutCPoint構造函數endl;nnCPoint(const CPoint&one)nnnPosX=one.nPosX;nPosY=one.nPosY;ncoutCPoint默認拷貝構造函數endl;nnCPoint()ncoutCPoint析構函數endl;public:int nPosX,nPosY;/為簡化代碼,將這里的數據成員定義成公有型;class CSize public:CSize(int l=0,int w=0)nLength=l;nWidth=w;if(0=l)&(0=w)coutCSize默認構造函數endl;elsecoutCSize
17、構造函數endl;CSize(CPoint pt1,CPoint pt2)nLength=pt2.nPosX-pt1.nPosX;nWidth=pt2.nPosY-pt1.nPosY;coutCSize(CPoint,CPoint)構造函數endl;CSize(const CSize&one)nLength=one.nLength;nWidth=one.nWidth;coutCSize默認拷貝構造函數endl;CSize()coutCSize析構函數endl;public:int nLength,nWidth;/為簡化代碼,將這里的數據成員定義成公有型;class CRectpublic:CR
18、ect(int left,int top,int right,int bottom):ptLT(left,top),ptRB(right,bottom),size(ptLT,ptRB),nLength(size.nLength)nWidth=size.nWidth;coutCRect構造函數endl;CRect()coutCRect析構函數endl;void show()cout-endl;coutsize:size.nLength,size.nWidthendl;coutptLT:ptLT.nPosX,ptLT.nPosYendl;coutptRB:ptRB.nPosX,ptRB.nPosY
19、endl;coutnLength:nLength,nWidth:nWidthendl;cout-endl;private:CPoint ptLT,ptRB;CSize size;int nLength,nWidth;int main()CRect rc(10,100,80,250);rc.show();return 0;程序運行結果如下:事實上,“CRect rc(10,100,80,250);”的構造過程可用圖來描述(圖中括號中的數字與分析步驟相對應)。n3.幾點說明n(1)對象成員必須初始化,且應盡量選擇由冒號“:”引導的對象初始化列表的初始化方式,以提高對象初始化效率。n(2)對象成員初
20、始化時,必須有相應的構造函數,且多個對象成員的構造次序不是按初始化成員列表的順序,也不是按各個類的聲明的先后順序,而是按對象成員在類中聲明的順序進行。n(3)對象成員初始化也可在類的外部進行,但必須與構造函數的定義在一起。n(4)成員初始化列表也可用于類中的普通數據成員的初始化,但要注意其初始化格式。n例如:nCRect(int left,int top,int right,int bottom)n:ptLT(left,top),ptRB(right,bottom),nsize(ptLT,ptRB),nnLength(size.nLength)/注意:不能是nLength=size.nLeng
21、thn/n10.3.4 const對象 n常對象的定義格式如下:const(初值)nconst (初值)10.3.5 對象的生存期n對象可分為如下三種:對象可分為如下三種:n(1)局部對象。)局部對象。n(2)靜態(tài)對象。)靜態(tài)對象。n(3)全局對象。)全局對象。10.4 綜合應用實例n1.棧模型n棧有兩種操作:npush(壓入)與pop(彈出)。例Ex_Stack10 設計棧類來存取學生成績數據。n#include n#include n#include nusing namespace std;nclass CStuScoren;nclass CStacknnpublic:nCStack(i
22、nt nSize=10);/構造函數nCStack();/析構函數npublic:/操作nvoidpush(CStuScore a);/壓入anCStuScorepop(void);/彈出nprivate:nCStuScore*sp;/棧頂指針nCStuScore*buffer;/??臻gnintm_nSize;/棧大小n;nint main()nnCStack one(5);/創(chuàng)建大小為5個學生成績對象的棧nCStuScore stu;nstu.Input();none.push(stu);/壓入nstu.SetData(DING,21010102,80,80,90);none.push(st
23、u);/壓入nstu.SetData(“ZHANG”,“21010103”,80,90,70);none.push(stu);/壓入ncout開始進行彈出操作!endl;nstu=one.pop();/彈出nstu.Output();nstu=one.pop();nstu.Output();/彈出nstu=one.pop();nstu.Output();nreturn 0;nnCStack:CStack(int nSize)n/初始化代碼nm_nSize=nSize;nbuffer=new CStuScorem_nSize;/開辟??臻gnif(buffer!=NULL)/開辟成功nsp=buf
24、fer;/初建時,sp指向棧底nelsenexit(1);/若開辟不成功,程序非正常終止ncout棧空間已成功建立!endl;/顯示成功的提示信息nnCStack:CStack()nnif(buffer)/判斷nndelete m_nSizebuffer;/釋放內存nbuffer=NULL;/一個好的習慣ncout??臻g已釋放!buffer+m_nSize)nncout棧空間不夠,棧溢出!endl;nexit(1);/程序非正常終止n elsen*sp+=a;/a寫入棧和sp+合寫一條語句nnCStuScore CStack:pop(void)nnsp-;nif(sp buffer)nncout已越過棧底!endl;nexit(1);/程序非正常終止n else nreturn *sp;/返回彈出的內容n程序運行結果如下: