學(xué)習(xí)工控軟件chap_第1頁(yè)
學(xué)習(xí)工控軟件chap_第2頁(yè)
學(xué)習(xí)工控軟件chap_第3頁(yè)
學(xué)習(xí)工控軟件chap_第4頁(yè)
學(xué)習(xí)工控軟件chap_第5頁(yè)
已閱讀5頁(yè),還剩91頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1第2章C++面向?qū)ο?程序設(shè)計(jì)2.1類和對(duì)象2.2數(shù)據(jù)共享和成員特性2.3繼承和派生2.4多態(tài)和虛函數(shù)2.5運(yùn)算符重載2.6輸入/輸出流2定義類:class<類名> {private: [<私有數(shù)據(jù)和函數(shù)>]

public: [<公有數(shù)據(jù)和函數(shù)>]

protected: [<保護(hù)型數(shù)據(jù)和函數(shù)>]};<各個(gè)成員函數(shù)的實(shí)現(xiàn)>2.1類和對(duì)象2.1.1類的定義類的聲明:聲明類中的成員類的實(shí)現(xiàn):對(duì)成員函數(shù)的定義數(shù)據(jù)成員:“屬性”成員函數(shù):“方法”怎么干可以干什么以C開頭注:數(shù)據(jù)不可直接初始化3成員函數(shù)在類體外定義,加作用域運(yùn)算符“::”ClassCMeter{ public: voidStepIt(); private: intm_nPos;}voidCMeter::StepIt(){ m_nPos++;}2.1類和對(duì)象4注意:(1)

數(shù)據(jù)成員的數(shù)據(jù)類型任意,但不允許對(duì)數(shù)據(jù)成員進(jìn)行初始化例:classCMeter{... private: intm_nPos=10; //錯(cuò)誤

};(2)

在“public:”或“private:”后面定義的所有成員都是公有或私有的,直到下一個(gè)“public:”或“private:”出現(xiàn)為止。默認(rèn)是private(私有)。(3)public和private可以在類中出現(xiàn)多次,前后的順序沒(méi)有關(guān)系;但最好先公有,后私有。(4)

通常將數(shù)據(jù)成員聲明為私有,而將成員函數(shù)聲明為公有。(5)

類的聲明放入.h文件,成員函數(shù)的實(shí)現(xiàn)放入同名的.cpp文件。2.1類和對(duì)象52.1.2對(duì)象的定義定義對(duì)象:<類名><對(duì)象名表>

對(duì)象既可以是一個(gè)普通對(duì)象,也可以是一個(gè)數(shù)組對(duì)象或指針對(duì)象。例如:CMetermyMeter,*Meter,Meters[2];訪問(wèn)對(duì)象的成員變量和成員函數(shù):在成員前面加上對(duì)象名和成員運(yùn)算符“.”(對(duì)象只能訪問(wèn)公有成員):

<對(duì)象名>.<成員變量><對(duì)象名>.<成員函數(shù)>(<參數(shù)表>)<對(duì)象指針名>-><成員變量>(*<對(duì)象指針名>).<成員變量>2.1類和對(duì)象62.1.3類作用域和成員訪問(wèn)權(quán)限類的作用域:類的定義中{}部分說(shuō)明:定義變量只能用static,不能用auto,register,extern若類的成員函數(shù)在類外定義,則類作用域直到函數(shù)定義結(jié)束例:classA{//類作用域開始

voidf();};voidA:f(){……}//類作用域結(jié)束2.1類和對(duì)象7類名的作用域:從定義一直到文件結(jié)束類中成員的可見性:

1.類中成員聲明的前后不會(huì)影響該成員在類中的使用例:classA{voidf(){cout<<a<<endl;}inta;};

2.

類作用域中的成員只可在類作用域中使用,在類外不行。

例:classA{publica;};a=10;//錯(cuò)誤,不能在類外直接使用類成員類外對(duì)象成員的可見性:類外對(duì)象只能訪問(wèn)public成員。2.1類和對(duì)象82.1.4構(gòu)造函數(shù)和析構(gòu)函數(shù)1.構(gòu)造函數(shù)功能:對(duì)象創(chuàng)建時(shí),進(jìn)行對(duì)象的初始化。特點(diǎn):在對(duì)象建立時(shí)它會(huì)被自動(dòng)執(zhí)行。規(guī)定:構(gòu)造函數(shù)必須與相應(yīng)的類同名,可以帶參數(shù),也可以不帶參數(shù),還可以帶默認(rèn)參數(shù),可以重載例如:classCMeter {public: CMeter(intnPos) //帶參數(shù)

{m_nPos=nPos; } ...}CMeteroMeter(10),oTick(20);說(shuō)明:構(gòu)造函數(shù)必須是public的,不需要指定返回值的類型2.1類和對(duì)象92.1.4構(gòu)造函數(shù)和析構(gòu)函數(shù)3.默認(rèn)構(gòu)造函數(shù)若類定義中沒(méi)有定義構(gòu)造函數(shù)時(shí),編譯自動(dòng)為類生成一個(gè)隱式的不帶參數(shù)的默認(rèn)構(gòu)造函數(shù)例CMeter() //默認(rèn)構(gòu)造函數(shù)的形式

{}例如:CMeterm1,m2;說(shuō)明:1.

默認(rèn)構(gòu)造函數(shù)將對(duì)象的所有數(shù)據(jù)成員都初始化為無(wú)效值(對(duì)象為自動(dòng)類型)或空值或0(對(duì)象為靜態(tài)類型)2.

若類中定義了構(gòu)造函數(shù),則隱式默認(rèn)構(gòu)造函數(shù)不再存在,但也可以在類中定義顯式的默認(rèn)構(gòu)造函數(shù)2.1類和對(duì)象104.析構(gòu)函數(shù)功能:與構(gòu)造函數(shù)相對(duì)應(yīng),釋放一個(gè)對(duì)象定義:在類名稱前面加上一個(gè)“~”符號(hào)。每個(gè)類只有一個(gè)析構(gòu)函數(shù),沒(méi)有任何參數(shù),也不返回任何值。例如:classCMeter{... ~CMeter() { }//析構(gòu)函數(shù)

};說(shuō)明:析構(gòu)函數(shù)可以由用戶調(diào)用也可以由系統(tǒng)自動(dòng)調(diào)用,若沒(méi)有定義析構(gòu)函數(shù),系統(tǒng)也會(huì)定義默認(rèn)的析構(gòu)函數(shù)析構(gòu)函數(shù)被自動(dòng)調(diào)用的情況:(1)當(dāng)對(duì)象定義在一個(gè)函數(shù)體中,該函數(shù)調(diào)用結(jié)束后;(2)用new為對(duì)象分配動(dòng)態(tài)內(nèi)存,當(dāng)使用delete釋放對(duì)象時(shí)。2.1類和對(duì)象11[例Ex_Name]構(gòu)造函數(shù)和析構(gòu)函數(shù)的使用#include<iostream.h>classCName{public: CName(char*str){strName=str;}char*getName(){returnstrName;}private: char*strName;};voidmain(){ char*p=newchar[5];strcpy(p,“ding”);CNameone(p);delete[]p;cout<<one.getName()<<endl;}2.1類和對(duì)象12改正:classCName{public:CName(){strName=NULL;} CName(char*str){strName=(char*)newchar[strlen(str)+1];strcpy(strName,str);}~CName(){if(strName)delete[]strName;strName=NULL;}char*getName(){returnstrName;}private: char*strName;};2.1類和對(duì)象135.對(duì)象賦值和拷貝1.賦值CNameone;//合法CNametwo(“DING”);//合法one=two;//語(yǔ)法合法,但程序會(huì)終止one(two);//語(yǔ)法合法,但程序會(huì)終止語(yǔ)法合法:默認(rèn)拷貝構(gòu)造函數(shù)(淺拷貝):類名(const類名&)當(dāng)對(duì)象作為函數(shù)參數(shù)時(shí),會(huì)自動(dòng)調(diào)用拷貝構(gòu)造函數(shù)程序終止:one的strName沒(méi)有賦初值2.1類和對(duì)象14深拷貝構(gòu)造函數(shù):特殊的成員函數(shù),用一個(gè)已知的對(duì)象來(lái)初始化一個(gè)被創(chuàng)建的同類的對(duì)象。第一個(gè)參數(shù)必須是是同類的一個(gè)對(duì)象的引用。定義形式:類名((const)<類名>&<引用名>)例:CName(CName&one)

{strName=(char*)newchar[strlen(str)+1]; strcpy(strName,str); }2.1類和對(duì)象152.1.6對(duì)象成員初始化組合類:把一個(gè)已定義類的對(duì)象作為另一個(gè)類的成員。構(gòu)造函數(shù)定義格式:<類名>::<構(gòu)造函數(shù)名>(形參表):對(duì)象1(參數(shù)表),對(duì)象2(參數(shù)表),…,對(duì)象n(參數(shù)表){}其中,對(duì)象1、對(duì)象2、…、對(duì)象n就是該類使用的其他類的對(duì)象,冒號(hào)“:”后面的列表稱為成員初始化列表。2.1類和對(duì)象16#include<iostream.h>classCPoint{……};classCRect{public: CRect(intx1,inty1,intx2,inty2)

:m_ptLT(x1,y1),m_ptRB(x2,y2){} private: CPointm_ptLT,m_ptRB;};intmain(){CRectrc(10,100,80,250);return0;}2.1類和對(duì)象17說(shuō)明:1.對(duì)象成員必須初始化,但不能將對(duì)象成員直接在構(gòu)造函數(shù)體內(nèi)進(jìn)行初始化。如下列方法錯(cuò)誤:

CRect(intx1,inty1,intx2,inty2)

{m_ptLT=CPoint(x1,y1);m_ptRB=CPoint(x2,y2);}2.

對(duì)象成員初始化時(shí),多個(gè)對(duì)象成員的構(gòu)造次序是按各成員聲明的先后次序進(jìn)行的,與:后初始化列表中的順序無(wú)關(guān)。2.1類和對(duì)象182.2.1靜態(tài)成員1.靜態(tài)數(shù)據(jù)成員同一個(gè)類中所有對(duì)象共享的成員。定義:step1:在類中使用關(guān)鍵字static聲明靜態(tài)數(shù)據(jù)成員, 僅僅為了說(shuō)明它是類中的成員這個(gè)關(guān)系。step2:在類外為靜態(tài)數(shù)據(jù)成員分配內(nèi)存空間并初始化初始化:<數(shù)據(jù)類型><類名>::<靜態(tài)數(shù)據(jù)成員名>=<值>引用:可用類名來(lái)引用,即<類名>::<靜態(tài)成員>

也可以通過(guò)對(duì)象名來(lái)引用即對(duì)象名.靜態(tài)成員2.2數(shù)據(jù)共享和成員特性19[例Ex_StaticData]靜態(tài)數(shù)據(jù)成員的使用classCSum{public: CSum(inta=0,intb=0){nSum+=a+b;} intGetSum(){returnnSum;} voidSetSum(intsum) { nSum=sum; }private: staticintnSum;//聲明靜態(tài)數(shù)據(jù)成員,虛的

};intCSum::nSum=0;//靜態(tài)數(shù)據(jù)成員的初始化,默認(rèn)為0voidmain(){ CSumone(10,2),two; cout<<"sum="<<one.GetSum()<<endl;cout<<"sum="<<two.GetSum()<<endl; one.SetSum(5); cout<<"sum="<<one.GetSum()<<endl; cout<<"sum="<<two.GetSum()<<endl;}2.2數(shù)據(jù)共享和成員特性20說(shuō)明:1.生存期從實(shí)際定義開始,程序結(jié)束時(shí)消失,不隨著對(duì)象的消失而釋放,也不能在構(gòu)造函數(shù)中創(chuàng)建或者在析構(gòu)函數(shù)中釋放。2.當(dāng)靜態(tài)數(shù)據(jù)成員是public時(shí),可通過(guò)對(duì)象或類名直接引用:

對(duì)象名.靜態(tài)數(shù)據(jù)

類名::靜態(tài)數(shù)據(jù)3.與普通靜態(tài)變量的“靜態(tài)”區(qū)分:普通靜態(tài)變量時(shí)存儲(chǔ)的一種方式,而靜態(tài)數(shù)據(jù)成員說(shuō)明對(duì)象對(duì)數(shù)據(jù)的共享2.2數(shù)據(jù)共享和成員特性212.靜態(tài)成員函數(shù)靜態(tài)成員函數(shù)是對(duì)象共享的成員函數(shù)它可以直接引用靜態(tài)成員,不能直接引用非靜態(tài)成員。靜態(tài)成員函數(shù)不屬于對(duì)象,屬于類。因此不創(chuàng)建對(duì)象也可通過(guò)類的名字調(diào)用成員函數(shù)。對(duì)靜態(tài)成員函數(shù)的引用可以通過(guò)類名也可以通過(guò)對(duì)象名普通函數(shù)在內(nèi)存中是動(dòng)態(tài)加載,而靜態(tài)成員函數(shù)只有當(dāng)程序結(jié)束的時(shí)候才從內(nèi)存消失2.2數(shù)據(jù)共享和成員特性22[例Ex_StaticFunc]靜態(tài)成員函數(shù)的使用#include<iostream.h>classCSum{public: CSum(inta=0,intb=0){nSum+=a+b;} intGetSum(){returnnSum;} voidSetSum(intsum){nSum=sum;}

staticvoidShowData(CSumone);//聲明靜態(tài)成員函數(shù)private: staticintnSum; };2.2數(shù)據(jù)共享和成員特性23voidCSum::ShowData(CSumone)//靜態(tài)成員函數(shù)的實(shí)現(xiàn){ cout<<"直接使用靜態(tài)成員"<<endl; cout<<"sum="<<nSum<<endl;//若nSum不是static,只能用下列方式訪問(wèn)

cout<<“使用同類的對(duì)象”<<endl;//普通成員函數(shù)既可以訪問(wèn)靜態(tài)成員也可訪問(wèn)非靜態(tài)成員

cout<<"sum="<<one.GetSum()<<endl;}intCSum::nSum=0; voidmain(){ CSumone(10,2); CSum::ShowData(one); //用所屬類名直接訪問(wèn)

one.SetSum(8); one.ShowData(one); //通過(guò)對(duì)象訪問(wèn)}2.2數(shù)據(jù)共享和成員特性242.2.2友元friend,類中聲明而類外定義,不是成員函數(shù),但可以訪問(wèn)私有和保護(hù)數(shù)據(jù)成員。破壞了類的封裝性,只在能提高效率時(shí)使用。定義:friend<函數(shù)類型><函數(shù)名>(形參表)說(shuō)明:友元函數(shù)不是類的成員,因此調(diào)用時(shí)不應(yīng)指明它的類,也不能通過(guò)對(duì)象來(lái)引用友元函數(shù)友元函數(shù)的定義可以在類內(nèi)也可以在類外,當(dāng)在類外定義時(shí),不應(yīng)像成員函數(shù)那樣指明它的類友元函數(shù)對(duì)類成員的訪問(wèn)只能通過(guò)對(duì)象進(jìn)行友元函數(shù)不受public,private等限制,可出現(xiàn)在類的任意位置2.2數(shù)據(jù)共享和成員特性25[例Ex_FriendFun]使用友元函數(shù)#include<iostream.h>classCPoint{friendCPointInflate(CPoint

&pt,intnOffset);

public:CPoint(intx=0,inty=0) { m_x=x; m_y=y; }voidPrint() { cout<<"Point("<<m_x<<","<<m_y<<")"<<endl;}private:unsigned m_x,m_y;};2.2數(shù)據(jù)共享和成員特性為了在函數(shù)中改變實(shí)參的值26CPointInflate(CPoint&ppt,intnOffset)//友元函數(shù)的定義{ ppt.m_x+=nOffset; //直接改變私有數(shù)據(jù)成員m_x和m_yppt.m_y+=nOffset;returnppt;}intmain(){CPointpt(10,20);pt.Print(); Inflate(pt,3); //調(diào)用友元函數(shù)

pt.Print();return0;}2.2數(shù)據(jù)共享和成員特性272.2.3常類型const,值不能被更改,定義或說(shuō)明的時(shí)候必須初始化。1.常對(duì)象定義:<類名>const<對(duì)象名>修飾符const可以放在類名后面,也可以放在類名前面。例如:classCOne{public:COne(inta,intb){x=a;y=b;}private:

intx,y;};constCOnea(3,4);COneconstb(5,6);其中,a和b都是COne對(duì)象常量,初始化后就不能再被更新。2.2數(shù)據(jù)共享和成員特性282.2.3常類型2.常指針const的不同位置:const在指針變量的類型之前,表示聲明一個(gè)指向常量的指針。此時(shí),在程序中不能通過(guò)指針來(lái)改變它所指向的數(shù)據(jù)值,但可以改變指針本身的值。聲明時(shí)賦不賦初值均可。 例如:inta=1,b=2; constint*p1=&a; *p1=2; //錯(cuò)誤,不能更改指針?biāo)赶虻臄?shù)據(jù)值

p1=&b; //指向常量的指針本身的值是可以改變的const放在指針定義語(yǔ)句的指針名前,表示指針本身是一個(gè)常量,稱為指針常量或常指針。因此,不能改變這種指針變量的值,但可以改變指變量所指向的數(shù)據(jù)值,聲明時(shí)必須賦初值。2.2數(shù)據(jù)共享和成員特性29

例如:inta=1,b=2; int*constp1=&a; int*constp2;//錯(cuò)誤,聲明指針常量時(shí)必須初始化 *p1=2; //正確,指針?biāo)赶虻臄?shù)據(jù)值可以改變

p1=&b; //錯(cuò)誤,指針常量本身的值是不可改變const在上述兩個(gè)地方都加,表示聲明一個(gè)指向常量的指針常量,指針本身的值不可改變,而且它所指向的數(shù)據(jù)的值也不能通過(guò)指針改變,聲明時(shí)必須賦初值。

例如:inta=1,b=2; constint*constpp=&a; *pp=2; //錯(cuò)誤,變量值不可變

pp=&b; //錯(cuò)誤,指針值不可變2.2數(shù)據(jù)共享和成員特性30[例Ex_ConstPara]常參數(shù)的函數(shù)傳遞#include<iostream.h>classCOne{public:

voidprint(constint*p,intn) //使用常參數(shù)

{ cout<<“{”<<*p;for(inti=1;i<n;i++) cout<<“,”<<*(p+i);cout<<“}”<<endl; }};voidmain(){intarray[6]={1,2,3,4,5,6}; COneone; one.print(array,6);}2.2數(shù)據(jù)共享和成員特性為了不需拷貝所有元素,所以用指針;為了不改變實(shí)參的值,所以用const312.2.3常類型3.常成員函數(shù)常成員函數(shù):使用const進(jìn)行聲明的成員函數(shù)。作用:只有常成員函數(shù)有資格操作常量或常對(duì)象函數(shù)說(shuō)明:<類型說(shuō)明符><函數(shù)名>(<參數(shù)表>)const;注意:const是加在函數(shù)說(shuō)明后面的類型修飾符,它是函數(shù)類型的一個(gè)組成部分,因此,在函數(shù)實(shí)現(xiàn)部分也要帶const關(guān)鍵字。2.2數(shù)據(jù)共享和成員特性32[例Ex_ConstFunc]常成員函數(shù)的使用#include<iostream.h>classCOne{public:COne(inta,intb){x=a;y=b;}voidprint();voidprint()const; //聲明常成員函數(shù)private:intx,y;};2.2數(shù)據(jù)共享和成員特性33voidCOne::print(){cout<<x<<","<<y<<endl; }voidCOne::print()const{cout<<"使用常成員函數(shù):"<<x<<","<<y<<endl; }voidmain(){COneone(5,4);one.print();constCOnetwo(20,52);two.print();}2.2數(shù)據(jù)共享和成員特性5,4使用常成員函數(shù):20,52344.常數(shù)據(jù)成員說(shuō)明:在類中聲明了const數(shù)據(jù)成員時(shí),只能通過(guò)成員初始化列表的方式來(lái)完成構(gòu)造函數(shù)對(duì)數(shù)據(jù)成員初始化。[例Ex_ConstData]常數(shù)據(jù)成員的使用#include<iostream.h>classCOne{public:

COne(inta):x(a),r(x) //常數(shù)據(jù)成員的初始化

{} voidprint(); constint&r; //引用類型的常數(shù)據(jù)成員2.2數(shù)據(jù)共享和成員特性35private: constintx; //常數(shù)據(jù)成員

staticconstinty; //靜態(tài)常數(shù)據(jù)成員};constintCOne::y=10; //靜態(tài)數(shù)據(jù)成員的初始化voidCOne::print(){cout<<"x="<<x<<",y="<<y<<",r="<<r<<endl; }voidmain(){COneone(100);one.print();}2.2數(shù)據(jù)共享和成員特性x=100,y=10,r=100362.2.4this指針this指針:僅能被類的非靜態(tài)成員函數(shù)訪問(wèn)。當(dāng)一個(gè)對(duì)象調(diào)用成員函數(shù)時(shí),編譯器先將對(duì)象的地址賦給this指針,然后調(diào)用成員函數(shù)。 例:調(diào)用one.copy(two);時(shí), 它實(shí)際上被解釋成:copy(&one,two); &one參數(shù)為隱藏了。說(shuō)明:通過(guò)*this可以判斷是哪個(gè)對(duì)象來(lái)調(diào)用該成員函數(shù)或重新指定對(duì)象。2.2數(shù)據(jù)共享和成員特性37[例Ex_This]this指針的使用#include<iostream.h> classCOne{public:COne(){x=y=0;}COne(inta,intb){x=a;y=b;}voidcopy(COne&a); //對(duì)象引用作函數(shù)參數(shù)

voidprint(){cout<<x<<","<<y<<endl;}private:intx,y;};2.2數(shù)據(jù)共享和成員特性38voidCOne::copy(COne&a){if(this==&a)return;*this=a;}voidmain(){COneone,two(3,4);one.print();one.copy(two);one.print();}2.2數(shù)據(jù)共享和成員特性0,03,4相當(dāng)于one=two;39基類、派生類、單繼承、多繼承注意:基類或基類的對(duì)象不能使用派生類的成員2.3.1.單繼承從一個(gè)基類定義一個(gè)派生類:

class<派生類名>:[<繼承方式>]<基類名>{ [<派生類的成員>]};繼承方式:public(公有)、private(私有)、protected(保護(hù)),默認(rèn)為private方式2.3繼承和派生類401.公有繼承(public)特點(diǎn):基類的公有成員和保護(hù)成員作為派生類的成員時(shí),它們都保持原有的狀態(tài),而基類的私有成員仍然是私有的。(可以被繼承,但無(wú)法直接訪問(wèn))classCMeter{public:GetPos(){returnm_npos;}private:m_nPos};classCStick:publicCMeter{ int m_nStickNum; //默認(rèn)為私有數(shù)據(jù)成員

public: voidDispStick(); //聲明一個(gè)公有成員函數(shù)

{ m_nStickNum=GetPos();//調(diào)用基類的成員函數(shù)

cout<<m_nStickNum<<’’; }};2.3繼承和派生類41[例Ex_PublicDerived]派生類的公有繼承示例classCMeter{public: CMeter(intnPos=10) {m_nPos=nPos;} voidStepIt(){m_nPos++;} intGetPos(){returnm_nPos;}protected: voidSetPos(intnPos){m_nPos=nPos;}private: intm_nPos;};classCStick:publicCMeter //從CMeter派生,公有繼承{ int m_nStickNum; //聲明一個(gè)私有數(shù)據(jù)成員

public: voidDispStick(); voidSetStick(intnPos){SetPos(nPos);}//類中調(diào)用基類的保護(hù)成員};2.3繼承和派生類42voidCStick::DispStick(){ m_nStickNum=GetPos(); //調(diào)用基類CMeter的成員函數(shù)

cout<<m_nStickNum<<'';}voidmain(){ CMeteroMeter(20); CStickoStick; cout<<"CMeter:"<<oMeter.GetPos()<<",CStick:"<<oStick.GetPos()<<endl;oMeter.StepIt();cout<<"CMeter:"<<oMeter.GetPos()<<",CStick:"<<oStick.GetPos()<<endl;oStick.StepIt();out<<"CMeter:"<<oMeter.GetPos()<<",CStick:"<<oStick.GetPos()<<endl;oStick.DispStick();oStick.StepIt();oStick.DispStick();}2.3繼承和派生類432.私有繼承(private)私有繼承:基類的公有成員和保護(hù)成員都作為派生類的私有成員。[例Ex_ClassPrivateDerived]派生類的私有繼承示例#include<iostream.h>classCMeter{public: CMeter(intnPos=10) {m_nPos=nPos;} ~CMeter(){ } voidStepIt(){m_nPos++;} intGetPos(){ returnm_nPos;}protected: voidSetPos(intnPos){m_nPos=nPos;}2.3繼承和派生類44private: intm_nPos;};classCStick:privateCMeter //從CMeter私有繼承{ int m_nStickNum; //聲明一個(gè)私有數(shù)據(jù)成員

public: voidDispStick(); //聲明一個(gè)公有成員函數(shù)

voidSetStick(intnPos){SetPos(nPos); } //調(diào)用基類的保護(hù)成員

intGetStick() { returnGetPos(); } //調(diào)用基類的公有成員};2.3繼承和派生類45voidCStick::DispStick(){ m_nStickNum=GetPos();//調(diào)用基類的公有成員函數(shù)

cout<<m_nStickNum<<'';}voidmain(){ CMeteroMeter(20); CStickoStick; cout<<"CMeter:"<<oMeter.GetPos()<<",CStick:"<<oStick.GetStick()<<endl; oMeter.StepIt(); cout<<"CMeter:"<<oMeter.GetPos()<<",CStick:"<<oStick.GetStick()<<endl; oStick.DispStick();}2.3繼承和派生類463.保護(hù)繼承(protected)特點(diǎn):基類的所有公有成員和保護(hù)成員都成為派生類的保護(hù)成員,并且只能被它的派生類成員函數(shù)或友元訪問(wèn)。繼承方式基類成員基類成員在派生類中的特性公有繼承(public)publicpublicprotectedprotectedprivate不可訪問(wèn)私有繼承(private)publicprivateprotectedprivateprivate不可訪問(wèn)保護(hù)繼承(protected)publicprotectedprotectedprotectedprivate不可訪問(wèn)2.3繼承和派生類472.3.2派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)基類的構(gòu)造函數(shù)和析構(gòu)函數(shù)不能被派生類繼承。當(dāng)派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)被執(zhí)行時(shí),基類相應(yīng)的構(gòu)造函數(shù)和析構(gòu)函數(shù)也會(huì)執(zhí)行。派生類對(duì)象建立時(shí),先執(zhí)行基類的構(gòu)造函數(shù),再執(zhí)行派生類的。析構(gòu)函數(shù)的執(zhí)行順序相反。[例Ex_ClassDerived]派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)的示例#include<iostream.h>#include<string.h>2.3繼承和派生類48classCAnimal{public: CAnimal(char*pName="noname"); ~CAnimal(){ cout<<"調(diào)用CAnimal的析構(gòu)函數(shù)!"<<endl; } voidsetName(char*pName) { strncpy(name,pName,sizeof(name)); } char*getName(void) {returnname; }private: charname[20];};CAnimal::CAnimal(char*pName){ setName(pName); cout<<"調(diào)用CAnimal的構(gòu)造函數(shù)!"<<endl;}2.3繼承和派生類49classCCat:publicCAnimal{public: CCat(){cout<<"調(diào)用CCat的構(gòu)造函數(shù)!"<<endl;} ~CCat(){cout<<"調(diào)用CCat的析造函數(shù)!"<<endl;} voidDispName() { cout<<"貓的名字是:"<<getName()<<endl; }};voidmain(){ CCatcat; cat.DispName(); cat.setName("Snoopy"); cat.DispName();}2.3繼承和派生類50對(duì)于派生類的構(gòu)造函數(shù),如果需要對(duì)基類設(shè)置初值,可用初始化列表進(jìn)行,即:派生類名(總參數(shù)表):基類1(參數(shù)表1),基類2(參數(shù)表2)…如:classCCat:publicCAnimal { public: CCat():CAnimal(“amiao”) {} …… };2.3繼承和派生類512.3.3多繼承定義:class<派生類名>:[<繼承方式1>]<基類名1>,[<繼承方式2>]<基類名2>,...{ [<派生類的成員>]};繼承方式:public、private和protected。例如:classCHorse {...}; classCBird {...}; classCFlyhorse:publicCHorse,privateCBird {...};2.3繼承和派生類522.3.4虛基類基類成員調(diào)用的二義性:多繼承下,對(duì)基類中某成員的訪問(wèn)可能出現(xiàn)不唯一的情況2.3繼承和派生類53例classCAnimal {public:CAnimal(){cout<<“GuesswhoamI”<<endl;} move(){cout<<“Idon’tknowhowtomove”<<endl;}}; classCHorse:publicCAnimal {public:CHorse(){cout<<“Iamahorse”<<endl;}}; classCBird:publicCAnimal {public:CBird(){cout<<“Iamabird”<<endl;}}; classCFlyhorse:publicCHorse,publicCBird {public: voidprint(){move();}//出錯(cuò),不知道是哪個(gè)x }; voidmain() { CFlyhorsehorse1; horse1.print(); }2.3繼承和派生類542.3.4虛基類解決二義性的方法之一是使用域作用運(yùn)算符“

::”,例如將print()函數(shù)實(shí)現(xiàn)代碼變?yōu)椋?/p>

voidprint() { CHorse::move(); CBird::move(); }2.3繼承和派生類552.3.4虛基類方法二:虛基類(虛繼承)聲明虛基類的格式:virtual<繼承方式><基類名>特點(diǎn):

所有派生類中只有一個(gè)基類的復(fù)制2.3繼承和派生類56例classCAnimal {public:CAnimal(){cout<<“GuesswhoamI”<<endl;} move(){cout<<“Idon’tknowhowtomove”<<endl;}}; classCHorse:virtualpublicCAnimal {public:CHorse(){cout<<“Iamahorse”<<endl;}}; classCBird:virtualpublicCAnimal {public:CBird(){cout<<“Iamabird”<<endl;}}; classCFlyhorse:publicCHorse,publicCBird {public: voidprint(){move();} }; voidmain() { CFlyhorsehorse1; horse1.print(); }2.3繼承和派生類57說(shuō)明:1.虛繼承下,派生類CHorse和CBird中只有基類CAnimal的一個(gè)拷貝2.建立CFlyhorse的對(duì)象時(shí),需要調(diào)用CAnimal的構(gòu)造函數(shù),因?yàn)橄到y(tǒng)不知道由CHorse還是CBird來(lái)調(diào)用CAnimal的構(gòu)造函數(shù),所以由CFlyhorse直接調(diào)用CAnimal的構(gòu)造函數(shù),然后分別調(diào)用CHorse和CBird的構(gòu)造函數(shù)。2.3繼承和派生類58多態(tài)性:不同類型的對(duì)象接收相同的信息時(shí)產(chǎn)生不同的行為。例如函數(shù)重載。分類:(1)編譯時(shí)的多態(tài)性:函數(shù)重載或運(yùn)算符重載。

(2)運(yùn)行時(shí)的多態(tài)性:虛函數(shù)。即在程序執(zhí)行之前,根據(jù)函數(shù)和參數(shù)無(wú)法確定應(yīng)該調(diào)用哪個(gè)函數(shù),必須在程序的執(zhí)行過(guò)程中,根據(jù)執(zhí)行情況動(dòng)態(tài)的確定。聯(lián)編:將一個(gè)標(biāo)識(shí)符和一個(gè)存儲(chǔ)地址聯(lián)系在一起的過(guò)程。分類:(1)靜態(tài)聯(lián)編:聯(lián)編在編譯階段完成。

(2)動(dòng)態(tài)聯(lián)編:聯(lián)編在程序運(yùn)行時(shí)動(dòng)態(tài)進(jìn)行。2.4多態(tài)和虛函數(shù)59虛函數(shù):定義:函數(shù)前加上virtual。作用:通過(guò)虛函數(shù),達(dá)到用基類指針訪問(wèn)派生類對(duì)象成員函數(shù)的目的。從而使一個(gè)函數(shù)具有不同的版本,不同版本在該基類的派生類中重新定義,實(shí)現(xiàn)了程序的運(yùn)行時(shí)多態(tài)。聯(lián)編:程序發(fā)現(xiàn)virtual關(guān)鍵詞后,會(huì)自動(dòng)將其作為動(dòng)態(tài)聯(lián)編處理2.4多態(tài)和虛函數(shù)60例:classCAnimal{public:CAnimal(){cout<<“GuesswhoamI”<<endl;}virtualvoidmove(){cout<<“Idon’tknowhowtomove”<<endl;}};classCHorse:publicCAnimal{public:CHorse(){cout<<“Iamahorse”<<endl;}voidmove(){cout<<“Imovewithmylegs”<<endl;}};classCBird:publicCAnimal{public:CBird(){cout<<“Iamabird”<<endl;}voidmove(){cout<<“Imovewithmywings”<<endl;}};voidmain(){CAnimal*p[2];p[0]=newCHorse;p[0]->move();p[1]=newCBird;p[1]->move();}2.4多態(tài)和虛函數(shù)61說(shuō)明:虛函數(shù)在重新定義時(shí)參數(shù)須和基類中的虛函數(shù)完全匹配(和函數(shù)重載區(qū)別)。虛函數(shù)必須是類的一個(gè)成員函數(shù),不能是友元函數(shù),也不能是靜態(tài)的成員函數(shù)。析構(gòu)函數(shù)可定義為虛函數(shù),構(gòu)造函數(shù)不能。主函數(shù)部分也可用&獲取地址,即:

CHorsehorse;p[0]=&horse;p[0]->move();2.4多態(tài)和虛函數(shù)62說(shuō)明:系統(tǒng)遇見關(guān)鍵字virtual時(shí)會(huì)采用動(dòng)態(tài)聯(lián)編只有通過(guò)指針才能實(shí)現(xiàn)虛函數(shù)的多態(tài)性

若有CAnimalp;p.move()只能調(diào)用CAnimal的move函數(shù)基類指針只能調(diào)用從基類繼承而來(lái)的函數(shù)。

若CHorse類中還有自己的函數(shù)sound(),則不能通過(guò)指針p[0]->sound();2.4多態(tài)和虛函數(shù)632.4.2純虛函數(shù)和抽象類聲明純虛函數(shù):

virtual<函數(shù)類型><函數(shù)名>(<形數(shù)表>)=0;

//本質(zhì)是將指向函數(shù)的指針的初值賦為0

純虛函數(shù)不能有具體的實(shí)現(xiàn)代碼抽象類:至少包含一個(gè)純虛函數(shù)的類。

不能聲明一個(gè)抽象類的對(duì)象。必須在派生類中定義了純虛函數(shù)的具體代碼,才能獲得派生類的對(duì)象。2.4多態(tài)和虛函數(shù)64例:classCAnimal//

抽象類{public:CAnimal(){cout<<“GuesswhoamI”<<endl;} virtualvoidmove()=0;};classCHorse:publicCAnimal{public:CHorse(){cout<<“Iamahorse”<<endl;}voidmove(){cout<<“Imovewithmylegs”<<endl;}};classCBird:publicCAnimal{public:CBird(){cout<<“Iamabird”<<endl;}voidmove(){cout<<“Imovewithmywings”<<endl;}};voidmain(){CAnimal*p[2];CHorsehorse;CBirdbird;p[0]=&horse;horse.move();p[0]->move();p[1]=&bird;bird.move();p[1]->move();}2.4多態(tài)和虛函數(shù)65應(yīng)用:類對(duì)象的運(yùn)算操作2.5.1運(yùn)算符重載函數(shù):

在類中聲明一個(gè)特殊的函數(shù),以通知編譯器。通常是類的成員函數(shù)或友元,操作數(shù)通常是該類的對(duì)象定義:<函數(shù)類型><類名>::operator<重載的運(yùn)算符>(<形參表>){…} //函數(shù)體2.5運(yùn)算符重載66[例plex]運(yùn)算符重載實(shí)現(xiàn)復(fù)數(shù)的相加#include<iostream.h>classplex{public:plex(doubler=0,doublei=0){ realPart=r; imagePart=i; } voidprint() {cout<<"實(shí)部="<<realPart<<",虛部="<<imagePart<<endl;} plexoperator+(plex&c);//重載運(yùn)算符+ plexoperator+(doubler); //重載運(yùn)算符+private: doublerealPart; //復(fù)數(shù)的實(shí)部 doubleimagePart; //復(fù)數(shù)的虛部};2.5運(yùn)算符重載67plexplex::operator+(plex&c){ plextemp; temp.realPart=realPart+c.realPart; temp.imagePart=imagePart+c.imagePart; returntemp;}plexplex::operator+(doubler){ plextemp;temp.realPart=realPart+r; temp.imagePart=imagePart; returntemp;}voidmain(){ plexc1(12,20),c2(50,70),c; c=c1+c2;//解釋為c1.operator+(c2) c.print();c=c1+20;c.print();}2.5運(yùn)算符重載68說(shuō)明:1.只能對(duì)C++中已定義的運(yùn)算符進(jìn)行重載,且不可改變運(yùn)算符的操作數(shù)個(gè)數(shù)、優(yōu)先級(jí)和結(jié)合性。2.用成員函數(shù)實(shí)現(xiàn)運(yùn)算符重載時(shí),左操作數(shù)一定是對(duì)象,右操作數(shù)可以是對(duì)象、對(duì)象的引用或其他類型的參數(shù)。3.?:.*.::sizeof不允許重載5.用類的成員函數(shù)進(jìn)行重載時(shí),參數(shù)個(gè)數(shù)比操作數(shù)少12.5運(yùn)算符重載692.5.3友元重載格式:friend<函數(shù)類型>operator<重載的運(yùn)算符>(<形參>) //單目運(yùn)算符重載,形參為對(duì)象或引用

{…} //函數(shù)體

friend<函數(shù)類型>operator<重載的運(yùn)算符>(<形參1,形數(shù)2>) //雙目運(yùn)算符重載

{…} //函數(shù)體說(shuō)明:=、()、[]和->,不能重載為友元函數(shù)2.5運(yùn)算符重載形參中必須有一個(gè)是類的對(duì)象70[例plexFriend]運(yùn)算符的友元重載#include<iostream.h> classplex{public: plex(doubler=0,doublei=0) { realPart=r; imagePart=i; } voidprint() {cout<<"實(shí)部="<<realPart<<",虛部="<<imagePart<<endl;} friendplexoperator+(doubler,plex&c);//友元重載+private:2.5運(yùn)算符重載71 doublerealPart; //復(fù)數(shù)的實(shí)部 doubleimagePart; //復(fù)數(shù)的虛部};plexoperator+(doubler,plex&c){ plextemp; temp.realPart=r+c.realPart; temp.imagePart=c.imagePart; returntemp;}voidmain(){ plexc1(12,20),c; c=20+c1; //友元 c.print();}2.5運(yùn)算符重載722.5.6自增和自減運(yùn)算符的重載后綴視為雙目:obj++或obj--重載時(shí):obj++0或obj—0++obj中返回的是obj自己,所以重載函數(shù)返回值是引用而不是對(duì)象例classplex{public:plex(doubler=0,doublei=0) { realPart=r; imagePart=i; } plexoperator++(); plexoperator++(int); voidprint() {cout<<"實(shí)部="<<realPart<<",虛部="<<imagePart<<endl;}private: doublerealPart,imagePart;};2.5運(yùn)算符重載73plexplex::operator++() //前綴++運(yùn)算符{ realPart++; return*this; }plexplex::operator++(int) //后綴++運(yùn)算符{plextemp; temp.realPart=realPart++;temp.imagePart=imagePart; returntemp;}voidmain(){plexdemo1,p1; for(inti=0;i<8;i++) p1=demo1++; demo1.print();p1.print(); plexdemo2; for(i=0;i<8;i++) ++demo2; demo2.print();}2.5運(yùn)算符重載輸出:實(shí)部=8,虛部=0實(shí)部=

7,虛部=0實(shí)部=

8,虛部=074例:綜合classplex{public:voidprint() {cout<<"實(shí)部="<<realPart<<",虛部="<<imagePart<<endl;} friendplexoperator+(doubler,plex&c);plexoperator+(plex&c); plexoperator+(doubler); plexoperator++(); plexoperator++(int);private: doublerealPart,imagePart; };2.5運(yùn)算符重載75plexplex::operator+(plex&c){ plextemp; temp.realPart=realPart+c.realPart; temp.imagePart=imagePart+c.imagePart; returntemp;}plexplex::operator+(doubler){ plextemp;temp.realPart=realPart+r; temp.imagePart=imagePart; returntemp;}plexoperator+(doubler,plex&c){ plextemp; temp.realPart=r+c.realPart; temp.imagePart=c.imagePart; returntemp;}2.5運(yùn)算符重載76plexplex::operator++(){ realPart++; return*this; }plexplex::operator++(int){plextemp; temp.realPart=realPart++;temp.imagePart=imagePart; returntemp;}voidmain(){ plexc1(12,20),c2(50,70),c; c=c1+c2; c=c1+20;c=20+c1;c=c1++;c=++c1;}2.5運(yùn)算符重載772.5.4轉(zhuǎn)換函數(shù)類型轉(zhuǎn)換:將一種類型的值映射為另一種類型的值轉(zhuǎn)換函數(shù):將類對(duì)象強(qiáng)制轉(zhuǎn)化成指定的數(shù)據(jù)類型;class<類名>{public:operator<類型>();…}operator和類型一起構(gòu)成了轉(zhuǎn)換函數(shù)名2.5運(yùn)算符重載要轉(zhuǎn)換的數(shù)據(jù)類型78轉(zhuǎn)換函數(shù)用法說(shuō)明:只能是成員函數(shù),不能是友元函數(shù),可以被派生類繼承,可以說(shuō)明為虛函數(shù)、一個(gè)類中可定義多個(gè)轉(zhuǎn)換函數(shù)[例Ex_Money]把數(shù)字金額轉(zhuǎn)換成大寫形式#include<iostream.h>#include<string.h>typedefchar*string;classCMoney{public: CMoney(doublea=0.0){ amount=a; } operatorstring();2.5運(yùn)算符重載79private: doubleamount;};CMoney::operatorstring(){ stringbasestr[15]={"分","角","元","拾","佰","仟","萬(wàn)","拾","佰","仟","億","拾","佰","仟","萬(wàn)"}; stringdatastr[10]={"零","壹","貳","叁","肆","伍","陸","柒","捌","玖"}; staticcharstrResult[80]; doubletemp,base=1.0; intn=0;2.5運(yùn)算符重載80temp=amount*100.0; strcpy(strResult,"金額為:"); if(temp<1.0)strcpy(strResult,"金額為:零元零角零分"); else { while(temp>=10.0) { //計(jì)算位數(shù)

base=base*10.0; temp=temp/10.0; n++; } if(n>=15)strcpy(strResult,"金額超過(guò)范圍!"); else { temp=amount*100.0; for(intm=n;m>=0;m--) { 2.5運(yùn)算符重載81 intd=(int)(temp/base); temp=temp-base*(double)d; base=base/10.0; strcat(strResult,datastr[d]); strcat(strResult,basestr[m]); } } }returnstrResult;}voidmain(){ CMoneymoney(1234123456789.123); cout<<(string)money<<endl;}2.5運(yùn)算符重載822.5.5賦值運(yùn)算符的重載classCdemo{public: CDemo(char*s) { ps=newchar[strlen(s)+1]; strcpy(ps,s); } ~CDemo() { if(ps)delete[]ps; } voidprint() { cout<<ps<<endl; }private: char*ps;};voidmain(){ CDemod1("Key"),d2("Mouse"); d1=d2;//運(yùn)行到此行時(shí)發(fā)生運(yùn)行錯(cuò)誤}2.5運(yùn)算符重載對(duì)象成員中有數(shù)組或動(dòng)態(tài)的數(shù)據(jù)類型時(shí),不能直接賦值83[例Ex_Evaluate]賦值運(yùn)算符的重載#include<iostream.h>#include<string.h>classCdemo{public: CDemo(char*s) { ps=newchar[strlen(s)+1]; strcpy(ps,s); } ~CDemo() { if(ps)delete[]ps; } voidprint() { cout<<ps<<endl; } CDemo&operator=(CDemo&a) //賦值運(yùn)算符重載

{ if(ps)delete[]ps;

2.5運(yùn)算符重載84if(a.ps){ ps=newchar[strlen(a.ps)+1]; strcpy(ps,a.ps); }elseps=0; return*this; }private: char*ps;};voidmain(){ CDemod1("Key"),d2("Mouse"); d1=d2; d1.print();}2.5運(yùn)算符重載852.6.1概述C語(yǔ)言兼容的輸入輸出函數(shù),printf()和scanf()等輸入輸出流庫(kù)ios“流”:數(shù)據(jù)從一個(gè)位置到另一個(gè)位置的流動(dòng)2.6輸入輸出流庫(kù)istream類ostream類iostream類ios類(虛)對(duì)流的狀態(tài)進(jìn)行設(shè)置publicpubliccin(對(duì)象)cout(對(duì)象)cerr,clog+862.6.2使用格式控制成員函數(shù)控制輸入輸出的數(shù)制、長(zhǎng)度、精度、填充字符等#include<iostream.h>intmain(){ doublevalues[]={1.23,35.36,653.7,4358.24,36}; for(inti=

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 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ì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論