C++程序設(shè)計(jì)第7章類和對象的基礎(chǔ)_第1頁
C++程序設(shè)計(jì)第7章類和對象的基礎(chǔ)_第2頁
C++程序設(shè)計(jì)第7章類和對象的基礎(chǔ)_第3頁
C++程序設(shè)計(jì)第7章類和對象的基礎(chǔ)_第4頁
C++程序設(shè)計(jì)第7章類和對象的基礎(chǔ)_第5頁
已閱讀5頁,還剩119頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第7章類和對象的基礎(chǔ)第7章類和對象的基礎(chǔ)1本章內(nèi)容提要類與對象的定義對象的初始化成員函數(shù)的特性靜態(tài)成員友元類的作用域與對象的生存期本章內(nèi)容提要類與對象的定義2一、類與對象的定義什么是類?類是一種新的數(shù)據(jù)類型。類是邏輯相關(guān)的函數(shù)和數(shù)據(jù)的封裝,是對所處理的問題的抽象描述,所以,類是實(shí)現(xiàn)抽象類型的工具。類(Class):是一種用戶定義的類型,它包括定義的數(shù)據(jù)和其對應(yīng)的操作(函數(shù))。使用對象將數(shù)據(jù)和操作進(jìn)行封裝(Encapsulation)。一、類與對象的定義什么是類?3什么是對象?類實(shí)例化后便生成對象。對象(Object):含有數(shù)據(jù)(對象的屬性Attribute)又含有對數(shù)據(jù)的操作代碼(Method)的一個(gè)邏輯封裝體。屬性:描述對象特征的數(shù)據(jù)。方法:對屬性的操作。面向?qū)ο缶幊汤脤ο筮M(jìn)行程序設(shè)計(jì)什么是對象?類實(shí)例化后便生成對象。41.類的定義類的定義一般分為說明部分和實(shí)現(xiàn)部分。說明部分:類中的成員數(shù)據(jù)成員成員函數(shù)的說明實(shí)現(xiàn)部分成員函數(shù)的具體定義例如:定義一個(gè)汽車類型號、外殼、車輪等(數(shù)據(jù)成員)啟動(dòng)、加速和停止等(成員函數(shù))1.類的定義類的定義5類的定義格式:class<類名>{

public:

<公有數(shù)據(jù)成員和成員函數(shù)的說明或?qū)崿F(xiàn)>

private:

<私有數(shù)據(jù)成員和成員函數(shù)的說明或?qū)崿F(xiàn)>protected:<保護(hù)數(shù)據(jù)成員和成員函數(shù)的說明或?qū)崿F(xiàn)>};

<各個(gè)成員函數(shù)的實(shí)現(xiàn)>類的定義格式:class<類名>6例:坐標(biāo)點(diǎn)類問題:將坐標(biāo)點(diǎn)與相應(yīng)操作封裝成類classTPoint{

public:

voidSetxy(inta,intb);//說明在類體內(nèi),定義在類體外

voidMove(int,int);//函數(shù)原型聲明,參數(shù)名可給可不給出

voidPrint();intGetx();intGety();

private:

intx,y;//數(shù)據(jù)成員};

例:坐標(biāo)點(diǎn)類問題:將坐標(biāo)點(diǎn)與相應(yīng)操作封裝成類classT7例:坐標(biāo)點(diǎn)類(續(xù)上)問題:將坐標(biāo)點(diǎn)與相應(yīng)操作封裝成類voidTPoint::Setxy(inta,intb){

x=a;y=b;}voidTPoint:move(inta,intb){

x=x+a;y=y+b;}voidTPoint::Print();{

cout<<"x="<<Getx()<<"y="<<Gety();}intTPoint::Getx(){returnx;}intTPoint::Gety(){returny;}在類體外定義成員函數(shù)的一般格式為:<函數(shù)類型><類名>::<成員函數(shù)>(<參數(shù)表>){<函數(shù)體>}其中,作用域運(yùn)算符“::”是用來標(biāo)識成員函數(shù)是屬于哪個(gè)類的,

“類名”是成員函數(shù)所屬類的名字。若在函數(shù)前加關(guān)鍵詞inline,

則成為內(nèi)聯(lián)成員函數(shù)。若函數(shù)較短,可以在類內(nèi)定義,也稱作

內(nèi)聯(lián)成員函數(shù)。例:坐標(biāo)點(diǎn)類(續(xù)上)問題:將坐標(biāo)點(diǎn)與相應(yīng)操作封裝成類voi8例:坐標(biāo)點(diǎn)類(內(nèi)聯(lián)函數(shù)形式)問題:將說明部分和實(shí)現(xiàn)部分都在類體內(nèi)定義。classTPoint//類名{

public://聲明其后為公有成員

voidSetxy(inta,intb){x=a;y=b;}voidMove(inta,intb){x=x+a;y=y+b;}voidPrint(){cout<<"x="<<Getx()<<"y="<<Gety();}intGetx(){returnx;}intGety(){returny;}

private:

intx,y;//數(shù)據(jù)成員};

例:坐標(biāo)點(diǎn)類(內(nèi)聯(lián)函數(shù)形式)問題:將說明部分和實(shí)現(xiàn)部分都在92.對象的定義與使用對象的定義格式:

<類名><對象名列表>說明:<類名>是定義對象所屬類的名字。<對象名列表>可有多個(gè)對象名,用逗號分隔。例如:TPointp1,p2;//定義TPoint類型的對象p1和p2。TPoint*p=&p1;//定義指向?qū)ο髉1的TPoint類型的指針p。TPoint&c=p2;//定義c為TPoint類型對象p2的引用。TPointm[5];//定義一個(gè)TPoint類型的對象數(shù)組。2.對象的定義與使用對象的定義格式:

<類名><對象102.對象的定義與使用對象中數(shù)據(jù)成員和成員函數(shù)的表示方式1:<對象名>.<成員名><對象名>.<成員名>(<參數(shù)表>)例如:p1.x,p1.y,p1.Setxy(2,3)對象中數(shù)據(jù)成員和成員函數(shù)的表示方式2:<對象指針名>-><成員名>或者(*<對象指針名>).<成員名><對象指針名>-><成員名>(<參數(shù)表>)或者(*<對象指針名>).<成員名>(<參數(shù)表>)例如:p->x,p->y,p->Getxy(inta,intb)或者(*p).x,(*p).y,(*p).Getxy(inta,intb)2.對象的定義與使用對象中數(shù)據(jù)成員和成員函數(shù)的表示方式1:11例7.1問題:對象的定義和成員函數(shù)的調(diào)用。#include<iostream.h>#include"Tpoint.h"voidmain(){TPointp1,p2;TPoint*p=&p1;p1.Setxy(1,2);cout<<"x="<<p1.Getx()<<"y="<<p1.Gety()<<endl;p2.Setxy(3,4);cout<<"x="<<p2.Getx()<<"y="<<p2.Gety()<<endl;p->Setxy(5,6);//或(*p).Setxy(5,6)cout<<"x="<<p->Getx()<<"y="<<p->Gety()<<endl;p1.Move(1,2);p2.Move(3,4);(*p).Move(5,6);//或p->Move(5,6);p1.Print();p2.Print();p->Print();}該程序的運(yùn)行結(jié)果為x=1y=2x=3y=4x=5y=6x=11y=14x=6y=8x=11y=14例7.1問題:對象的定義和成員函數(shù)的調(diào)用。#include12對象定義的實(shí)質(zhì)定義一個(gè)類,就相當(dāng)于定義了一種類型,它并不會接受或存儲具體的值,只作為一個(gè)樣板,只有被實(shí)例化生成對象以后,系統(tǒng)才為對象分配存儲空間。為節(jié)省內(nèi)存,在創(chuàng)建對象時(shí),只為每個(gè)對象的數(shù)據(jù)成員分配內(nèi)存,而成員函數(shù)只是一次性存放在靜態(tài)存儲區(qū)中,為所有的對象共享。例如:TPointp1,p2;類TPointintx,yvoidSetxy(inta,intb);voidMove(int,int);voidPrint();intGetx();intGety();p1對象intx,yp2對象intx,y對象定義的實(shí)質(zhì)定義一個(gè)類,就相當(dāng)于定義了一種類型,它并不會接13二、對象的初始化在類的定義中,無法用表達(dá)式初始化數(shù)據(jù)成員,因此,在聲明一個(gè)對象時(shí),對象的初始狀態(tài)是不確定的,需要初始化。對象初始化可以使用:構(gòu)造函數(shù)析構(gòu)函數(shù)復(fù)制構(gòu)造函數(shù)二、對象的初始化在類的定義中,無法用表達(dá)式初始化數(shù)據(jù)成員,141.構(gòu)造函數(shù)構(gòu)造函數(shù)是一種特殊的成員函數(shù),它主要用來為對象分配空間,給他的數(shù)據(jù)成員賦值(初始化)并執(zhí)行對象的其他內(nèi)部管理操作。說明:構(gòu)造函數(shù)的名字必須與類的名字相同,并且構(gòu)造函數(shù)無返回值,不允許定義構(gòu)造函數(shù)的返回值類型,包括void類型。但允許有參數(shù)。構(gòu)造函數(shù)是成員函數(shù),函數(shù)體可寫在類體內(nèi),也可寫在類體外。構(gòu)造函數(shù)可以重載。注意:構(gòu)造函數(shù)在對象創(chuàng)建時(shí)由系統(tǒng)自動(dòng)調(diào)用,這是它與類的普通成員函數(shù)之間的最大區(qū)別。構(gòu)造函數(shù)的定義格式如下:<類名>::<構(gòu)造函數(shù)名>{<函數(shù)體>}1.構(gòu)造函數(shù)構(gòu)造函數(shù)是一種特殊的成員函數(shù),它主要用來為對象15例7.2問題:構(gòu)造函數(shù)的定義舉例。#include<iostream>classTpoint{public:Tpoint(intm,intn){x=m;y=n;}//定義構(gòu)造函數(shù)intGetx(){returnx;}intGety(){returny;}private:intx,y;};voidmain(){Tpointa(10,20);Tpointb(15,25);cout<<a.Getx()<<","<<a.Gety()<<endl;cout<<b.Getx()<<","<<b.Gety()<<endl;}該程序的運(yùn)行結(jié)果如下:10,2015,25例7.2問題:構(gòu)造函數(shù)的定義舉例。#include<io162.析構(gòu)函數(shù)析構(gòu)函數(shù)也是類中的特殊成員函數(shù),與類名字相象,在前加一個(gè)波浪號“~”。它沒有參數(shù),也沒有返回值,在一個(gè)類中只能有一個(gè)析構(gòu)函數(shù)。析構(gòu)函數(shù)執(zhí)行與構(gòu)造函數(shù)相反的操作。通常用于釋放分配給對象的存儲空間,當(dāng)程序超出類對象的作用域時(shí),或者當(dāng)對一個(gè)類指針使用運(yùn)算符delete時(shí),將自動(dòng)執(zhí)行析構(gòu)函數(shù)。說明:和構(gòu)造函數(shù)一樣,如果不定義析構(gòu)函數(shù),編譯程序?qū)⑻峁┮粋€(gè)缺省的析構(gòu)函數(shù)。對大多數(shù)類來說,缺省的析構(gòu)函數(shù)就能滿足要求,如果在一個(gè)對象完成其操作之前還需要做一些內(nèi)部處理,則應(yīng)顯式的定義析構(gòu)函數(shù)。析構(gòu)函數(shù)的定義格式如下:<類名>::~<析構(gòu)函數(shù)名>{<函數(shù)體>}注意:析構(gòu)函數(shù)僅能有一個(gè),不能重載。2.析構(gòu)函數(shù)析構(gòu)函數(shù)也是類中的特殊成員函數(shù),與類名字相象,17例7.3問題:構(gòu)造函數(shù)和析構(gòu)函數(shù)舉例。#include<iostream>classTpoint{public: Tpoint(intm,intn){x=m;y=n;}//定義構(gòu)造函數(shù) ~Tpoint();intGetx(){returnx;} intGety(){returny;}private:intx,y;};Tpoint::~Tpoint(){cout<<"Destructorcalled.\n";}voidmain(){Tpointa(10,20);Tpointb(15,25);cout<<a.Getx()<<","<<a.Gety()<<endl;cout<<b.Getx()<<","<<b.Gety()<<endl;}該程序的運(yùn)行結(jié)果如下:10,2015,25Destructorcalled.Destructorcalled.例7.3問題:構(gòu)造函數(shù)和析構(gòu)函數(shù)舉例。#include<18類的構(gòu)造函數(shù)和析構(gòu)函數(shù)注意:類的構(gòu)造函數(shù)在程序中為對象創(chuàng)建時(shí)分配系統(tǒng)資源提供了初始化的方法;析構(gòu)函數(shù)為對象撤銷時(shí)釋放系統(tǒng)資源提供了方法。無論用戶是否定義構(gòu)造函數(shù)和析構(gòu)函數(shù),它們都默認(rèn)存在。只要定義了新類,類的對象在創(chuàng)建和撤銷時(shí),構(gòu)造函數(shù)和析構(gòu)函數(shù)將會被調(diào)用。類的構(gòu)造函數(shù)和析構(gòu)函數(shù)注意:類的構(gòu)造函數(shù)在程序中為對象創(chuàng)建時(shí)193.復(fù)制構(gòu)造函數(shù)已有變量可以初始化另一個(gè)變量:inta=5;intb=a;同樣,已有對象也可以初始化另一個(gè)對象。復(fù)制構(gòu)造函數(shù)是一種特殊的成員函數(shù),其功能是用一個(gè)已經(jīng)初始化過了的對象去初始化另一個(gè)新創(chuàng)建的對象。復(fù)制構(gòu)造函數(shù)的定義格式如下:<類名>::<復(fù)制構(gòu)造函數(shù)名>(<類名>&<引用名>){<函數(shù)體>}注意:它只有一個(gè)參數(shù),是對某個(gè)對象的引用。3.復(fù)制構(gòu)造函數(shù)已有變量可以初始化另一個(gè)變量:20例7.4問題:調(diào)用復(fù)制構(gòu)造函數(shù)的例子。#include<iostream>classTpoint{public: Tpoint(intm,intn);//定義構(gòu)造函數(shù) ~Tpoint();//定義析構(gòu)函數(shù) Tpoint(Tpoint&r);//定義復(fù)制構(gòu)造函數(shù)intGetx(){returnx;}intGety(){returny;}private:intx,y;};Tpoint::Tpoint(intm,intn){cout<<"Callconstructor.\n";x=m;y=n;}Tpoint::Tpoint(Tpoint&r){cout<<"Copyconstructor.\n";x=r.x;y=r.y;}Tpoint::~Tpoint(){cout<<"Destructorcalled.\n";}例7.4問題:調(diào)用復(fù)制構(gòu)造函數(shù)的例子。#include<21例7.4問題:調(diào)用復(fù)制構(gòu)造函數(shù)的例子。voidmain(){Tpointa(10,20);Tpointb(15,25);Tpointc(a);cout<<a.Getx()<<","<<a.Gety()<<endl;cout<<b.Getx()<<","<<b.Gety()<<endl;cout<<c.Getx()<<","<<c.Gety()<<endl;}該程序的運(yùn)行結(jié)果為:Callconstructor.Callconstructor.Copyconstructor.10,2015,2510,20Destructorcalled.Destructorcalled.Destructorcalled.例7.4問題:調(diào)用復(fù)制構(gòu)造函數(shù)的例子。voidmain(227.3成員函數(shù)的特性成員函數(shù)除了說明和定義之外,還有一些相關(guān)的特性:內(nèi)聯(lián)函數(shù)和外聯(lián)函數(shù)成員函數(shù)重載設(shè)置參數(shù)的缺省值7.3成員函數(shù)的特性成員函數(shù)除了說明和定義之外,還有一些相231.內(nèi)聯(lián)函數(shù)和外聯(lián)函數(shù)類的成員函數(shù)可以分為內(nèi)聯(lián)函數(shù)和外聯(lián)函數(shù)。內(nèi)聯(lián)函數(shù)是指那些定義在類體內(nèi)的成員函數(shù),即該函數(shù)的函數(shù)體放在類體內(nèi)。而說明在類體內(nèi),定義在類體外的成員函數(shù)叫外聯(lián)函數(shù)。外聯(lián)函數(shù)的函數(shù)體在類的實(shí)現(xiàn)部分。兩者的區(qū)別:一般函數(shù)進(jìn)行調(diào)用時(shí),要將程序執(zhí)行權(quán)轉(zhuǎn)到被調(diào)用函數(shù)中,然后再返回到調(diào)用它的函數(shù)中;而內(nèi)聯(lián)函數(shù)則是在編譯時(shí),將調(diào)用表達(dá)式用內(nèi)聯(lián)函數(shù)體來替換。這樣在使用時(shí)去掉了調(diào)用環(huán)節(jié),提高運(yùn)行速度。缺點(diǎn):如果內(nèi)聯(lián)函數(shù)代碼過大,則目標(biāo)程序會加大。1.內(nèi)聯(lián)函數(shù)和外聯(lián)函數(shù)類的成員函數(shù)可以分為內(nèi)聯(lián)函數(shù)和外聯(lián)函數(shù)24例7.5問題:內(nèi)聯(lián)函數(shù)與外聯(lián)函數(shù)實(shí)例。#include<iostream.h>classA{public:A(intm,intn)//內(nèi)聯(lián)函數(shù),定義在類體內(nèi){x=m;y=n;}intGetx(){returnx;}//內(nèi)聯(lián)函數(shù),定義在類體內(nèi)intGety(){returny;}//內(nèi)聯(lián)函數(shù),定義在類體內(nèi)intsumxy();//內(nèi)聯(lián)函數(shù),定義在類體外,但進(jìn)行了轉(zhuǎn)化intarea();//外聯(lián)函數(shù),定義在類體外private:intx,y;};inlineintA::sumxy()//由外聯(lián)函數(shù)轉(zhuǎn)化為內(nèi)聯(lián)函數(shù){returnGetx()+Gety();}intA::area(){returnGetx()*Gety();}voidmain(){As(10,20);cout<<"sum="<<s.sumxy()<<","<<"area="<<s.area()<<endl;}在使用內(nèi)聯(lián)函數(shù)時(shí),應(yīng)注意以下幾點(diǎn):(1)在內(nèi)聯(lián)函數(shù)內(nèi)不允許用循環(huán)語句和開關(guān)語句。(2)內(nèi)聯(lián)函數(shù)的定義必須出現(xiàn)在內(nèi)聯(lián)函數(shù)第一次被調(diào)用之前。(3)內(nèi)聯(lián)函數(shù)無法進(jìn)行遞歸調(diào)用。例7.5問題:內(nèi)聯(lián)函數(shù)與外聯(lián)函數(shù)實(shí)例。#include<252.成員函數(shù)重載在前面介紹的成員函數(shù)中,除了析構(gòu)函數(shù)不能重載外,其他的成員函數(shù)都可以進(jìn)行重載。但重載必須滿足以下條件之一:參數(shù)個(gè)數(shù)不同。參數(shù)類型不同。當(dāng)參數(shù)個(gè)數(shù)相同時(shí),參數(shù)類型至少有一個(gè)不同。僅有返回值不同的函數(shù)是不能重載的。2.成員函數(shù)重載在前面介紹的成員函數(shù)中,除了析構(gòu)函數(shù)不能重26例7.6問題:成員函數(shù)重載實(shí)例。#include<iostream.h>classB{public:B(inta){x=a+1;y=a;}B(inta,intb){x=a;y=b;}intadd();intadd(inta);intadd(inta,intb);intGetx(){returnx;}intGety(){returny;}private:intx,y;};intB::add(){returnx+y;}intB::add(inta){x=y=a;returnx+y;}intB::add(inta,intb){x=a;y=b;returnx+y;}例7.6問題:成員函數(shù)重載實(shí)例。#include<iost27例7.6問題:成員函數(shù)重載實(shí)例。voidmain(){Bm(5,7),n(6);cout<<"m="<<m.Getx()<<","<<m.Gety()<<endl;cout<<"n="<<n.Getx()<<","<<n.Gety()<<endl;inti=m.add();intj=m.add(1,2);intk=n.add(4);cout<<i<<endl<<j<<endl<<k<<endl;}該程序的運(yùn)行結(jié)果為:m=5,7n=7,61238例7.6問題:成員函數(shù)重載實(shí)例。voidmain()該程283.設(shè)置參數(shù)的缺省值成員函數(shù)和普通函數(shù)一樣,可以設(shè)置參數(shù)的缺省值。一般的成員函數(shù)和構(gòu)造函數(shù)都可以被設(shè)置參數(shù)的缺省值。3.設(shè)置參數(shù)的缺省值成員函數(shù)和普通函數(shù)一樣,可以設(shè)置參數(shù)的29例7.7問題:設(shè)置默認(rèn)參數(shù)應(yīng)用舉例。#include<iostream>usingnamespacestd;classB{public: B(inta=10,intb=20,intc=30); intGetx(){returnx;} intGety(){returny;}

intGetz(){returnz;}private:intx,y,z;};B::B(inta,intb,intc){x=a;y=b;z=c;}例7.7問題:設(shè)置默認(rèn)參數(shù)應(yīng)用舉例。#include<io30例7.7問題:設(shè)置默認(rèn)參數(shù)應(yīng)用舉例。voidmain(){Bi,j(1),k(1,2),r(1,2,3);cout<<"i="<<i.Getx()<<""<<i.Gety()<<""<<i.Getz()<<endl;cout<<"j="<<j.Getx()<<""<<j.Gety()<<""<<j.Getz()<<endl;cout<<"k="<<k.Getx()<<""<<k.Gety()<<""<<k.Getz()<<endl;cout<<"r="<<r.Getx()<<""<<r.Gety()<<""<<r.Getz()<<endl;}該程序的運(yùn)行結(jié)果為:i=102030j=12030k=1230r=123例7.7問題:設(shè)置默認(rèn)參數(shù)應(yīng)用舉例。voidmain()31四、靜態(tài)成員靜態(tài)成員可以實(shí)現(xiàn)多個(gè)對象之間的數(shù)據(jù)共享,并且使用靜態(tài)成員還不會破壞隱藏的原則,保證了安全性。靜態(tài)數(shù)據(jù)成員靜態(tài)成員函數(shù)四、靜態(tài)成員靜態(tài)成員可以實(shí)現(xiàn)多個(gè)對象之間的數(shù)據(jù)共享,并且使321.靜態(tài)數(shù)據(jù)成員靜態(tài)數(shù)據(jù)成員是類的所有對象中共享的成員,而不是某個(gè)對象的成員。彌補(bǔ)了全局變量的不足,它相對于類中的“全局變量”。注意:靜態(tài)成員所占空間不會隨著對象的產(chǎn)生而分配,隨著對象的消失而回收。1.靜態(tài)數(shù)據(jù)成員靜態(tài)數(shù)據(jù)成員是類的所有對象中共享的成員,而33例7.8問題:靜態(tài)數(shù)據(jù)成員定義。#include<iostream>usingnamespacestd;classtime{public:time(int,int);voiddisplay();private: staticinthour;//hour是一個(gè)靜態(tài)數(shù)據(jù)成員。intminute;intsecond;};例7.8問題:靜態(tài)數(shù)據(jù)成員定義。#include<ios34例7.8問題:靜態(tài)數(shù)據(jù)成員定義。time::time(intm,ints):minute(m),second(s){};inttime::hour=15;voidtime::display(){cout<<hour<<":"<<minute<<":"<<second<<endl;}voidmain(){timet1(06,20),t2(10,30);t1.display();t2.display();}該程序的運(yùn)行結(jié)果為:15:6:2015:10:30例7.8問題:靜態(tài)數(shù)據(jù)成員定義。time::time(in35說明:靜態(tài)數(shù)據(jù)成員的初始化應(yīng)在類體外進(jìn)行,其格式如下:<數(shù)據(jù)類型><類名>::<靜態(tài)數(shù)據(jù)成員名>=<初值>例如,inttime::hour=15;在數(shù)據(jù)成員前不加static,而應(yīng)使用作用域運(yùn)算符來表明所屬類。在程序中如果靜態(tài)數(shù)據(jù)成員的訪問權(quán)限為公有(public)成員,則可按如下格式引用:<類名>::<靜態(tài)成員名>//前面直接用類名靜態(tài)數(shù)據(jù)成員被存放在靜態(tài)存儲區(qū)。說明:靜態(tài)數(shù)據(jù)成員的初始化應(yīng)在類體外進(jìn)行,其格式如下:362.靜態(tài)成員函數(shù)在靜態(tài)成員函數(shù)的實(shí)現(xiàn)中,可以直接引用靜態(tài)成員,但不能直接引用非靜態(tài)成員,如果要引用非靜態(tài)成員時(shí),可通過對象來引用。對靜態(tài)成員函數(shù)的引用,在程序中一般使用下列格式:類名.靜態(tài)成員函數(shù)(參數(shù)表)有時(shí),也可以由對象來引用,格式如下:對象.靜態(tài)成員函數(shù)(參數(shù)表)2.靜態(tài)成員函數(shù)在靜態(tài)成員函數(shù)的實(shí)現(xiàn)中,可以直接引用靜態(tài)成37例7.9問題:靜態(tài)成員函數(shù)對非靜態(tài)成員的引用。#include<iostream.h>classtest{public:test(inta){A=a;B+=a;}

staticvoidf(testm);

//靜態(tài)公有成員函數(shù)聲明private:

intA;

staticintB;//靜態(tài)私有成員};例7.9問題:靜態(tài)成員函數(shù)對非靜態(tài)成員的引用。#inclu38例7.9問題:靜態(tài)成員函數(shù)對非靜態(tài)成員的引用。inttest::B=0;//靜態(tài)成員初始化voidtest::f(testm){cout<<"A="<<m.A<<endl;//引用類的非靜態(tài)成員,用對象引用cout<<"B="<<B<<endl;//引用類的靜態(tài)成員,直接引用}voidmain(){testX(10),Y(20);test::f(X);//調(diào)用靜態(tài)成員函數(shù)test::f(Y);//調(diào)用靜態(tài)成員函數(shù)}該程序的運(yùn)行結(jié)果為:例7.9問題:靜態(tài)成員函數(shù)對非靜態(tài)成員的引用。intte39靜態(tài)成員函數(shù)的使用注意:只能訪問類的靜態(tài)數(shù)據(jù)成員,而不能直接訪問類中的普通成員(需用點(diǎn)域法)靜態(tài)成員函數(shù)與類相聯(lián)系,而不與類的對象相聯(lián)系,所以在類的外部調(diào)用類中的公有靜態(tài)成員函數(shù),必須在其左面加"類名::",而不是通過對象名調(diào)用公有靜態(tài)成員函數(shù)。在類的外部不能調(diào)用類中的私有靜態(tài)成員函數(shù)。靜態(tài)成員函數(shù)的使用注意:只能訪問類的靜態(tài)數(shù)據(jù)成員,而不能直接40五、友元為了方便類內(nèi)數(shù)據(jù)的訪問,提出友元方案。兩種形式友元函數(shù)友元類特點(diǎn):破壞了類的封閉性和隱藏性,但是提高了程序的運(yùn)行效率。五、友元為了方便類內(nèi)數(shù)據(jù)的訪問,提出友元方案。411.友元函數(shù)友元函數(shù)是定義在類外部的普通函數(shù),但對它的說明是在類內(nèi)部,在友元函數(shù)的說明前加關(guān)鍵字friend。友元函數(shù)說明格式:friend類型友元函數(shù)名(參數(shù)表);在類外定義友元函數(shù)的格式:類型函數(shù)名(類&對象);注意:友元函數(shù)不是成員函數(shù),但可以訪問類中的私有成員。聲明可在私有部分,也可在公有部分,作用相同。友元函數(shù)的調(diào)用方式于普通函數(shù)相同。1.友元函數(shù)友元函數(shù)是定義在類外部的普通函數(shù),但對它的說明是42Private:成員……public:pubf();……f()外部函數(shù)間接訪問Private:成員……public:pubf();friendf();……f()友元函數(shù)指定友元關(guān)系直接訪問無友元關(guān)系有友元關(guān)系友元函數(shù)關(guān)系示意圖Private:f()外部函數(shù)間接訪問Private:f(43例7.10問題:友元函數(shù)與普通函數(shù)。#include<iostream>usingnamespacestd;classStudent{private:intx;friendvoidgetf(Student&s);//在類中聲明友元函數(shù)getf()};voidgetf(Student&s)//定義友元函數(shù){s.x=10;

//友元函數(shù)通過對象引用類的私有成員cout<<s.x<<endl;}voidmain(){Students;getf(s);//調(diào)用該友元函數(shù)}該程序的運(yùn)行結(jié)果為:10例7.10問題:友元函數(shù)與普通函數(shù)。#include<io44例7.10問題:友元函數(shù)與普通函數(shù)。#include<iostream>usingnamespacestd;classStudent{private:intx;public:voidget()

//成員函數(shù){x=20;cout<<x<<endl;}};voidmain(){Students;s.get();}該程序的運(yùn)行結(jié)果為:20例7.10問題:友元函數(shù)與普通函數(shù)。#include<io452.友元類當(dāng)希望一個(gè)類可以存取另一個(gè)類的私有成員時(shí),可以將該類聲明為另一個(gè)類的友元類。此時(shí),該類的所有成員函數(shù)都可以訪問另一個(gè)類中的所有成員。定義友元類的語句格式如下:friendclass<類名>;其中:friend和class是關(guān)鍵字,類名必須是程序中的一個(gè)已定義過的類。2.友元類當(dāng)希望一個(gè)類可以存取另一個(gè)類的私有成員時(shí),可以將該46類X……friendclassY;類Y友元非友元使用友元類注意事項(xiàng):類X類YfriendclassX;類ZfriendclassY;友元友元非友元是單向的。如類A是類B的友元,但類B并不是類A的友元。不具有傳遞性。若類X是類Y的友元,類Y是類Z的友元,但類X不是類Z的友元。類X類Y友元非友元使用友元類注意事項(xiàng):類X類Y類Z友元友元非47例7.11問題:友元類實(shí)例。#include<iostream>usingnamespacestd;classX;classY{public:Y(){strcpy(cname,"計(jì)算機(jī)語言");}voidprint(){cout<<cname<<endl;}

friendclassX;//友元類的聲明private:charcname[30];};例7.11問題:友元類實(shí)例。#include<iostr48例7.11問題:友元類實(shí)例。classX{public:X(char*na,char*ena)

{strcpy(X::name,na);strcpy(X::ename,ena);}voidEditcname(Y&temp);

voidprint(){cout<<name<<endl;cout<<ename<<endl;}private:charname[20];charename[30];};voidX::Editcname(Y&temp){strcpy(ame,"計(jì)算機(jī)高級語言");}例7.11問題:友元類實(shí)例。classX49例7.11問題:友元類實(shí)例。voidmain(){

Xa("C++語言程序設(shè)計(jì)",

"TheC++ProgrammingLanguage.");Yb;a.Editcname(b);a.print(); b.print();}該程序的運(yùn)行結(jié)果為:C++語言程序設(shè)計(jì)TheC++ProgrammingLanguage.計(jì)算機(jī)高級語言例7.11問題:友元類實(shí)例。voidmain()該程序的50六、類的作用域類的作用域簡稱類域,它是指類的定義和相應(yīng)成員函數(shù)的定義范圍。注意:一個(gè)類在類域內(nèi)對任何成員都是開放的,而對類域外的類或函數(shù)的訪問受到限制。在類域中定義的變量不能使用auto,register和extern等修飾符,只能用static修飾符,而定義的函數(shù)也不能用extern修飾符。類本身可被定義在三種作用域內(nèi):全局作用域。(一般的C++類)在另一個(gè)類的作用域中。(嵌套類)在一個(gè)塊的局部作用域中。(局部類)六、類的作用域類的作用域簡稱類域,它是指類的定義和相應(yīng)成員函51例問題:全局作用域。intfork(void);//全局fork函數(shù)classProcess{intfork(void);......};成員函數(shù)fork隱藏了全局函數(shù)fork,前者能通過單目域運(yùn)算符調(diào)用后者:intProcess::fork(void){intpid=::fork();//調(diào)用全局fork函數(shù)......}例問題:全局作用域。intfork(void);52例問題:嵌套類的例子。classRectangle{public:Rectangle(int,int,int,int);……private:

classPoint

{public:Point(int,int);private:intx,y;};PointtopLeft,botRight;};Rectangle::Point::Point(intx,inty)

{

…...

}同樣,在類域外訪問嵌套類需要限制類名,例如:Rectangle::Pointpt(1,1);例問題:嵌套類的例子。classRectangle53例問題:局部類的例子。voidRender(Image&image){classColorTable{public:ColorTable(void){/*...*/}AddEntry(intr,intg,intb){/*...*/}…...};ColorTablecolors;…...}例問題:局部類的例子。voidRender(Image54例問題:綜合例子。classa{

intx;

//類變量x說明public:

intfun();

//類成員函數(shù)fun()說明}intx;

//全局變量x的說明intfun();

//全局函數(shù)fun()的說明inta::fun()

//類a中fun()成員函數(shù)的定義

{

::x++;

//全局變量x,必須用“::”來引用

returnx;

//類的成員x

}例問題:綜合例子。classa552.對象的生存期不同存儲的對象生存期不同。對象的生存期是指對象從被創(chuàng)建開始到被釋放為止的時(shí)間。按生存期的不同對象可分為如下三種:局部對象靜態(tài)對象全局對象2.對象的生存期不同存儲的對象生存期不同。對象的生存期是指561.局部對象當(dāng)對象被定義時(shí)調(diào)用構(gòu)造函數(shù),該對象被創(chuàng)建;當(dāng)程序退出定義該對象所在的函數(shù)體或程序塊時(shí),調(diào)用析構(gòu)函數(shù),釋放該對象。注意:一般定義在一個(gè)函數(shù)體或程序塊內(nèi),它的作用域小,生存期短。1.局部對象當(dāng)對象被定義時(shí)調(diào)用構(gòu)造函數(shù),該對象被創(chuàng)建;572.靜態(tài)對象當(dāng)程序第一次執(zhí)行所定義的靜態(tài)對象時(shí),該對象被創(chuàng)建,當(dāng)程序結(jié)束時(shí),該對象被釋放。注意:定義在一個(gè)文件中,它的作用域從定義時(shí)起到文件結(jié)束時(shí)止。2.靜態(tài)對象當(dāng)程序第一次執(zhí)行所定義的靜態(tài)對象時(shí),該對象被創(chuàng)建583.全局對象當(dāng)程序開始時(shí),調(diào)用構(gòu)造函數(shù)創(chuàng)建該對象。當(dāng)程序結(jié)束時(shí)調(diào)用析構(gòu)函數(shù)釋放該對象。注意:被定義在某個(gè)文件中,它的作用域在包含該文件的整個(gè)程序中。3.全局對象當(dāng)程序開始時(shí),調(diào)用構(gòu)造函數(shù)創(chuàng)建該對象。59例7.12問題:不同對象生存期實(shí)例。#include<iostream.h>classA{public:A(int);~A();private:intx;};A::A(inta){x=a;cout<<"Thenumberis:"<<x<<endl;}A::~A(){cout<<"Destructorcalledno."<<x<<endl;}例7.12問題:不同對象生存期實(shí)例。#include<io60例7.12問題:不同對象生存期實(shí)例。voidf1(){AA5(5);//局部對象cout<<"Inf1()"<<endl;}AA1(1);

//全局對象staticAA2(2);

//外部靜態(tài)對象voidmain(){staticAA3(3);

//內(nèi)部靜態(tài)對象AA4(4);

//局部對象cout<<"Inmain()beforecallf1."<<endl;f1();cout<<"Inmain()aftercallf1."<<endl;}該程序的運(yùn)行結(jié)果為:Thenumberis:1Thenumberis:2Thenumberis:3Thenumberis:4Inmain()beforecallf1.Thenumberis:5Inf1()Destructorcalledno.5Inmain()aftercallf1.Destructorcalledno.4Destructorcalledno.3Destructorcalledno.2Destructorcalledno.1例7.12問題:不同對象生存期實(shí)例。voidf1()該程61小結(jié)類是一種復(fù)雜的數(shù)據(jù)類型,它是抽象數(shù)據(jù)類型的實(shí)現(xiàn),是數(shù)據(jù)和相關(guān)操作的封裝體.類的定義分兩部分:說明和實(shí)現(xiàn)對象是類的一個(gè)實(shí)例,它是屬于某個(gè)已知類的。小結(jié)類是一種復(fù)雜的數(shù)據(jù)類型,它是抽象數(shù)據(jù)類型的實(shí)現(xiàn),是數(shù)據(jù)和62第7章類和對象的基礎(chǔ)第7章類和對象的基礎(chǔ)63本章內(nèi)容提要類與對象的定義對象的初始化成員函數(shù)的特性靜態(tài)成員友元類的作用域與對象的生存期本章內(nèi)容提要類與對象的定義64一、類與對象的定義什么是類?類是一種新的數(shù)據(jù)類型。類是邏輯相關(guān)的函數(shù)和數(shù)據(jù)的封裝,是對所處理的問題的抽象描述,所以,類是實(shí)現(xiàn)抽象類型的工具。類(Class):是一種用戶定義的類型,它包括定義的數(shù)據(jù)和其對應(yīng)的操作(函數(shù))。使用對象將數(shù)據(jù)和操作進(jìn)行封裝(Encapsulation)。一、類與對象的定義什么是類?65什么是對象?類實(shí)例化后便生成對象。對象(Object):含有數(shù)據(jù)(對象的屬性Attribute)又含有對數(shù)據(jù)的操作代碼(Method)的一個(gè)邏輯封裝體。屬性:描述對象特征的數(shù)據(jù)。方法:對屬性的操作。面向?qū)ο缶幊汤脤ο筮M(jìn)行程序設(shè)計(jì)什么是對象?類實(shí)例化后便生成對象。661.類的定義類的定義一般分為說明部分和實(shí)現(xiàn)部分。說明部分:類中的成員數(shù)據(jù)成員成員函數(shù)的說明實(shí)現(xiàn)部分成員函數(shù)的具體定義例如:定義一個(gè)汽車類型號、外殼、車輪等(數(shù)據(jù)成員)啟動(dòng)、加速和停止等(成員函數(shù))1.類的定義類的定義67類的定義格式:class<類名>{

public:

<公有數(shù)據(jù)成員和成員函數(shù)的說明或?qū)崿F(xiàn)>

private:

<私有數(shù)據(jù)成員和成員函數(shù)的說明或?qū)崿F(xiàn)>protected:<保護(hù)數(shù)據(jù)成員和成員函數(shù)的說明或?qū)崿F(xiàn)>};

<各個(gè)成員函數(shù)的實(shí)現(xiàn)>類的定義格式:class<類名>68例:坐標(biāo)點(diǎn)類問題:將坐標(biāo)點(diǎn)與相應(yīng)操作封裝成類classTPoint{

public:

voidSetxy(inta,intb);//說明在類體內(nèi),定義在類體外

voidMove(int,int);//函數(shù)原型聲明,參數(shù)名可給可不給出

voidPrint();intGetx();intGety();

private:

intx,y;//數(shù)據(jù)成員};

例:坐標(biāo)點(diǎn)類問題:將坐標(biāo)點(diǎn)與相應(yīng)操作封裝成類classT69例:坐標(biāo)點(diǎn)類(續(xù)上)問題:將坐標(biāo)點(diǎn)與相應(yīng)操作封裝成類voidTPoint::Setxy(inta,intb){

x=a;y=b;}voidTPoint:move(inta,intb){

x=x+a;y=y+b;}voidTPoint::Print();{

cout<<"x="<<Getx()<<"y="<<Gety();}intTPoint::Getx(){returnx;}intTPoint::Gety(){returny;}在類體外定義成員函數(shù)的一般格式為:<函數(shù)類型><類名>::<成員函數(shù)>(<參數(shù)表>){<函數(shù)體>}其中,作用域運(yùn)算符“::”是用來標(biāo)識成員函數(shù)是屬于哪個(gè)類的,

“類名”是成員函數(shù)所屬類的名字。若在函數(shù)前加關(guān)鍵詞inline,

則成為內(nèi)聯(lián)成員函數(shù)。若函數(shù)較短,可以在類內(nèi)定義,也稱作

內(nèi)聯(lián)成員函數(shù)。例:坐標(biāo)點(diǎn)類(續(xù)上)問題:將坐標(biāo)點(diǎn)與相應(yīng)操作封裝成類voi70例:坐標(biāo)點(diǎn)類(內(nèi)聯(lián)函數(shù)形式)問題:將說明部分和實(shí)現(xiàn)部分都在類體內(nèi)定義。classTPoint//類名{

public://聲明其后為公有成員

voidSetxy(inta,intb){x=a;y=b;}voidMove(inta,intb){x=x+a;y=y+b;}voidPrint(){cout<<"x="<<Getx()<<"y="<<Gety();}intGetx(){returnx;}intGety(){returny;}

private:

intx,y;//數(shù)據(jù)成員};

例:坐標(biāo)點(diǎn)類(內(nèi)聯(lián)函數(shù)形式)問題:將說明部分和實(shí)現(xiàn)部分都在712.對象的定義與使用對象的定義格式:

<類名><對象名列表>說明:<類名>是定義對象所屬類的名字。<對象名列表>可有多個(gè)對象名,用逗號分隔。例如:TPointp1,p2;//定義TPoint類型的對象p1和p2。TPoint*p=&p1;//定義指向?qū)ο髉1的TPoint類型的指針p。TPoint&c=p2;//定義c為TPoint類型對象p2的引用。TPointm[5];//定義一個(gè)TPoint類型的對象數(shù)組。2.對象的定義與使用對象的定義格式:

<類名><對象722.對象的定義與使用對象中數(shù)據(jù)成員和成員函數(shù)的表示方式1:<對象名>.<成員名><對象名>.<成員名>(<參數(shù)表>)例如:p1.x,p1.y,p1.Setxy(2,3)對象中數(shù)據(jù)成員和成員函數(shù)的表示方式2:<對象指針名>-><成員名>或者(*<對象指針名>).<成員名><對象指針名>-><成員名>(<參數(shù)表>)或者(*<對象指針名>).<成員名>(<參數(shù)表>)例如:p->x,p->y,p->Getxy(inta,intb)或者(*p).x,(*p).y,(*p).Getxy(inta,intb)2.對象的定義與使用對象中數(shù)據(jù)成員和成員函數(shù)的表示方式1:73例7.1問題:對象的定義和成員函數(shù)的調(diào)用。#include<iostream.h>#include"Tpoint.h"voidmain(){TPointp1,p2;TPoint*p=&p1;p1.Setxy(1,2);cout<<"x="<<p1.Getx()<<"y="<<p1.Gety()<<endl;p2.Setxy(3,4);cout<<"x="<<p2.Getx()<<"y="<<p2.Gety()<<endl;p->Setxy(5,6);//或(*p).Setxy(5,6)cout<<"x="<<p->Getx()<<"y="<<p->Gety()<<endl;p1.Move(1,2);p2.Move(3,4);(*p).Move(5,6);//或p->Move(5,6);p1.Print();p2.Print();p->Print();}該程序的運(yùn)行結(jié)果為x=1y=2x=3y=4x=5y=6x=11y=14x=6y=8x=11y=14例7.1問題:對象的定義和成員函數(shù)的調(diào)用。#include74對象定義的實(shí)質(zhì)定義一個(gè)類,就相當(dāng)于定義了一種類型,它并不會接受或存儲具體的值,只作為一個(gè)樣板,只有被實(shí)例化生成對象以后,系統(tǒng)才為對象分配存儲空間。為節(jié)省內(nèi)存,在創(chuàng)建對象時(shí),只為每個(gè)對象的數(shù)據(jù)成員分配內(nèi)存,而成員函數(shù)只是一次性存放在靜態(tài)存儲區(qū)中,為所有的對象共享。例如:TPointp1,p2;類TPointintx,yvoidSetxy(inta,intb);voidMove(int,int);voidPrint();intGetx();intGety();p1對象intx,yp2對象intx,y對象定義的實(shí)質(zhì)定義一個(gè)類,就相當(dāng)于定義了一種類型,它并不會接75二、對象的初始化在類的定義中,無法用表達(dá)式初始化數(shù)據(jù)成員,因此,在聲明一個(gè)對象時(shí),對象的初始狀態(tài)是不確定的,需要初始化。對象初始化可以使用:構(gòu)造函數(shù)析構(gòu)函數(shù)復(fù)制構(gòu)造函數(shù)二、對象的初始化在類的定義中,無法用表達(dá)式初始化數(shù)據(jù)成員,761.構(gòu)造函數(shù)構(gòu)造函數(shù)是一種特殊的成員函數(shù),它主要用來為對象分配空間,給他的數(shù)據(jù)成員賦值(初始化)并執(zhí)行對象的其他內(nèi)部管理操作。說明:構(gòu)造函數(shù)的名字必須與類的名字相同,并且構(gòu)造函數(shù)無返回值,不允許定義構(gòu)造函數(shù)的返回值類型,包括void類型。但允許有參數(shù)。構(gòu)造函數(shù)是成員函數(shù),函數(shù)體可寫在類體內(nèi),也可寫在類體外。構(gòu)造函數(shù)可以重載。注意:構(gòu)造函數(shù)在對象創(chuàng)建時(shí)由系統(tǒng)自動(dòng)調(diào)用,這是它與類的普通成員函數(shù)之間的最大區(qū)別。構(gòu)造函數(shù)的定義格式如下:<類名>::<構(gòu)造函數(shù)名>{<函數(shù)體>}1.構(gòu)造函數(shù)構(gòu)造函數(shù)是一種特殊的成員函數(shù),它主要用來為對象77例7.2問題:構(gòu)造函數(shù)的定義舉例。#include<iostream>classTpoint{public:Tpoint(intm,intn){x=m;y=n;}//定義構(gòu)造函數(shù)intGetx(){returnx;}intGety(){returny;}private:intx,y;};voidmain(){Tpointa(10,20);Tpointb(15,25);cout<<a.Getx()<<","<<a.Gety()<<endl;cout<<b.Getx()<<","<<b.Gety()<<endl;}該程序的運(yùn)行結(jié)果如下:10,2015,25例7.2問題:構(gòu)造函數(shù)的定義舉例。#include<io782.析構(gòu)函數(shù)析構(gòu)函數(shù)也是類中的特殊成員函數(shù),與類名字相象,在前加一個(gè)波浪號“~”。它沒有參數(shù),也沒有返回值,在一個(gè)類中只能有一個(gè)析構(gòu)函數(shù)。析構(gòu)函數(shù)執(zhí)行與構(gòu)造函數(shù)相反的操作。通常用于釋放分配給對象的存儲空間,當(dāng)程序超出類對象的作用域時(shí),或者當(dāng)對一個(gè)類指針使用運(yùn)算符delete時(shí),將自動(dòng)執(zhí)行析構(gòu)函數(shù)。說明:和構(gòu)造函數(shù)一樣,如果不定義析構(gòu)函數(shù),編譯程序?qū)⑻峁┮粋€(gè)缺省的析構(gòu)函數(shù)。對大多數(shù)類來說,缺省的析構(gòu)函數(shù)就能滿足要求,如果在一個(gè)對象完成其操作之前還需要做一些內(nèi)部處理,則應(yīng)顯式的定義析構(gòu)函數(shù)。析構(gòu)函數(shù)的定義格式如下:<類名>::~<析構(gòu)函數(shù)名>{<函數(shù)體>}注意:析構(gòu)函數(shù)僅能有一個(gè),不能重載。2.析構(gòu)函數(shù)析構(gòu)函數(shù)也是類中的特殊成員函數(shù),與類名字相象,79例7.3問題:構(gòu)造函數(shù)和析構(gòu)函數(shù)舉例。#include<iostream>classTpoint{public: Tpoint(intm,intn){x=m;y=n;}//定義構(gòu)造函數(shù) ~Tpoint();intGetx(){returnx;} intGety(){returny;}private:intx,y;};Tpoint::~Tpoint(){cout<<"Destructorcalled.\n";}voidmain(){Tpointa(10,20);Tpointb(15,25);cout<<a.Getx()<<","<<a.Gety()<<endl;cout<<b.Getx()<<","<<b.Gety()<<endl;}該程序的運(yùn)行結(jié)果如下:10,2015,25Destructorcalled.Destructorcalled.例7.3問題:構(gòu)造函數(shù)和析構(gòu)函數(shù)舉例。#include<80類的構(gòu)造函數(shù)和析構(gòu)函數(shù)注意:類的構(gòu)造函數(shù)在程序中為對象創(chuàng)建時(shí)分配系統(tǒng)資源提供了初始化的方法;析構(gòu)函數(shù)為對象撤銷時(shí)釋放系統(tǒng)資源提供了方法。無論用戶是否定義構(gòu)造函數(shù)和析構(gòu)函數(shù),它們都默認(rèn)存在。只要定義了新類,類的對象在創(chuàng)建和撤銷時(shí),構(gòu)造函數(shù)和析構(gòu)函數(shù)將會被調(diào)用。類的構(gòu)造函數(shù)和析構(gòu)函數(shù)注意:類的構(gòu)造函數(shù)在程序中為對象創(chuàng)建時(shí)813.復(fù)制構(gòu)造函數(shù)已有變量可以初始化另一個(gè)變量:inta=5;intb=a;同樣,已有對象也可以初始化另一個(gè)對象。復(fù)制構(gòu)造函數(shù)是一種特殊的成員函數(shù),其功能是用一個(gè)已經(jīng)初始化過了的對象去初始化另一個(gè)新創(chuàng)建的對象。復(fù)制構(gòu)造函數(shù)的定義格式如下:<類名>::<復(fù)制構(gòu)造函數(shù)名>(<類名>&<引用名>){<函數(shù)體>}注意:它只有一個(gè)參數(shù),是對某個(gè)對象的引用。3.復(fù)制構(gòu)造函數(shù)已有變量可以初始化另一個(gè)變量:82例7.4問題:調(diào)用復(fù)制構(gòu)造函數(shù)的例子。#include<iostream>classTpoint{public: Tpoint(intm,intn);//定義構(gòu)造函數(shù) ~Tpoint();//定義析構(gòu)函數(shù) Tpoint(Tpoint&r);//定義復(fù)制構(gòu)造函數(shù)intGetx(){returnx;}intGety(){returny;}private:intx,y;};Tpoint::Tpoint(intm,intn){cout<<"Callconstructor.\n";x=m;y=n;}Tpoint::Tpoint(Tpoint&r){cout<<"Copyconstructor.\n";x=r.x;y=r.y;}Tpoint::~Tpoint(){cout<<"Destructorcalled.\n";}例7.4問題:調(diào)用復(fù)制構(gòu)造函數(shù)的例子。#include<83例7.4問題:調(diào)用復(fù)制構(gòu)造函數(shù)的例子。voidmain(){Tpointa(10,20);Tpointb(15,25);Tpointc(a);cout<<a.Getx()<<","<<a.Gety()<<endl;cout<<b.Getx()<<","<<b.Gety()<<endl;cout<<c.Getx()<<","<<c.Gety()<<endl;}該程序的運(yùn)行結(jié)果為:Callconstructor.Callconstructor.Copyconstructor.10,2015,2510,20Destructorcalled.Destructorcalled.Destructorcalled.例7.4問題:調(diào)用復(fù)制構(gòu)造函數(shù)的例子。voidmain(847.3成員函數(shù)的特性成員函數(shù)除了說明和定義之外,還有一些相關(guān)的特性:內(nèi)聯(lián)函數(shù)和外聯(lián)函數(shù)成員函數(shù)重載設(shè)置參數(shù)的缺省值7.3成員函數(shù)的特性成員函數(shù)除了說明和定義之外,還有一些相851.內(nèi)聯(lián)函數(shù)和外聯(lián)函數(shù)類的成員函數(shù)可以分為內(nèi)聯(lián)函數(shù)和外聯(lián)函數(shù)。內(nèi)聯(lián)函數(shù)是指那些定義在類體內(nèi)的成員函數(shù),即該函數(shù)的函數(shù)體放在類體內(nèi)。而說明在類體內(nèi),定義在類體外的成員函數(shù)叫外聯(lián)函數(shù)。外聯(lián)函數(shù)的函數(shù)體在類的實(shí)現(xiàn)部分。兩者的區(qū)別:一般函數(shù)進(jìn)行調(diào)用時(shí),要將程序執(zhí)行權(quán)轉(zhuǎn)到被調(diào)用函數(shù)中,然后再返回到調(diào)用它的函數(shù)中;而內(nèi)聯(lián)函數(shù)則是在編譯時(shí),將調(diào)用表達(dá)式用內(nèi)聯(lián)函數(shù)體來替換。這樣在使用時(shí)去掉了調(diào)用環(huán)節(jié),提高運(yùn)行速度。缺點(diǎn):如果內(nèi)聯(lián)函數(shù)代碼過大,則目標(biāo)程序會加大。1.內(nèi)聯(lián)函數(shù)和外聯(lián)函數(shù)類的成員函數(shù)可以分為內(nèi)聯(lián)函數(shù)和外聯(lián)函數(shù)86例7.5問題:內(nèi)聯(lián)函數(shù)與外聯(lián)函數(shù)實(shí)例。#include<iostream.h>classA{public:A(intm,intn)//內(nèi)聯(lián)函數(shù),定義在類體內(nèi){x=m;y=n;}intGetx(){returnx;}//內(nèi)聯(lián)函數(shù),定義在類體內(nèi)intGety(){returny;}//內(nèi)聯(lián)函數(shù),定義在類體內(nèi)intsumxy();//內(nèi)聯(lián)函數(shù),定義在類體外,但進(jìn)行了轉(zhuǎn)化intarea();//外聯(lián)函數(shù),定義在類體外private:intx,y;};inlineintA::sumxy()//由外聯(lián)函數(shù)轉(zhuǎn)化為內(nèi)聯(lián)函數(shù){returnGetx()+Gety();}intA::area(){returnGetx()*Gety();}voidmain(){As(10,20);cout<<"sum="<<s.sumxy()<<","<<"area="<<s.area()<<endl;}在使用內(nèi)聯(lián)函數(shù)時(shí),應(yīng)注意以下幾點(diǎn):(1)在內(nèi)聯(lián)函數(shù)內(nèi)不允許用循環(huán)語句和開關(guān)語句。(2)內(nèi)聯(lián)函數(shù)的定義必須出現(xiàn)在內(nèi)聯(lián)函數(shù)第一次被調(diào)用之前。(3)內(nèi)聯(lián)函數(shù)無法進(jìn)行遞歸調(diào)用。例7.5問題:內(nèi)聯(lián)函數(shù)與外聯(lián)函數(shù)實(shí)例。#include<872.成員函數(shù)重載在前面介紹的成員函數(shù)中,除了析構(gòu)函數(shù)不能重載外,其他的成員函數(shù)都可以進(jìn)行重載。但重載必須滿足以下條件之一:參數(shù)個(gè)數(shù)不同。參數(shù)類型不同。當(dāng)參數(shù)個(gè)數(shù)相同時(shí),參數(shù)類型至少有一個(gè)不同。僅有返回值不同的函數(shù)是不能重載的。2.成員函數(shù)重載在前面介紹的成員函數(shù)中,除了析構(gòu)函數(shù)不能重88例7.6問題:成員函數(shù)重載實(shí)例。#include<iostream.h>classB{public:B(inta){x=a+1;y=a;}B(inta,intb){x=a;y=b;}intadd();intadd(inta);intadd(inta,intb);intGetx(){returnx;}intGety(){returny;}private:intx,y;};intB::add(){returnx+y;}intB::add(inta){x=y=a;returnx+y;}intB::add(inta,intb){x=a;y=b;returnx+y;}例7.6問題:成員函數(shù)重載實(shí)例。#include<iost89例7.6問題:成員函數(shù)重載實(shí)例。voidmain(){Bm(5,7),n(6);cout<<"m="<<m.Getx()<<","<<m.Gety()<<endl;cout<<"n="<<n.Getx()<<","<<n.Gety()<<endl;inti=m.add();intj=m.add(1,2);intk=n.add(4);cout<<i<<endl<<j<<endl<<k<<endl;}該程序的運(yùn)行結(jié)果為:m=5,7n=7,61238例7.6問題:成員函數(shù)重載實(shí)例。voidmain()該程903.設(shè)置參數(shù)的缺省值成員函數(shù)和普通函數(shù)一樣,可以設(shè)置參數(shù)的缺省值。一般的成員函數(shù)和構(gòu)造函數(shù)都可以被設(shè)置參數(shù)的缺省值。3.設(shè)置參數(shù)的缺省值成員函數(shù)和普通函數(shù)一樣,可以設(shè)置參數(shù)的91例7.7問題:設(shè)置默認(rèn)參數(shù)應(yīng)用舉例。#include<iostream>usingnamespacestd;classB{public: B(inta=10,intb=20,intc=30); intGetx(){returnx;} intGety(){returny;}

intGetz(){returnz;}private:intx,y,z;};B::B(inta,intb,intc){x=a;y=b;z=c;}例7.7問題:設(shè)置默認(rèn)參數(shù)應(yīng)用舉例。#include<io92例7.7問題:設(shè)置默認(rèn)參數(shù)應(yīng)用舉例。voidmain(){Bi,j(1),k(1,2),r(1,2,3);cout<<"i="<<i.Getx()<<""<<i.Gety()<<""<<i.Getz()<<endl;cout<<"j="<<j.Getx()<<""<<j.Gety()<<""<<j.Getz()<<endl;cout<<"k="<<k.Getx()<<""<<k.Gety()<<""<<k.Getz()<<endl;cout<<"r="<<r.Getx()<<""<<r.Gety()<<""<<r.Getz()<<endl;}該程序的運(yùn)行結(jié)果為:i=102030j=12030k=1230r=123例7.7問題:設(shè)置默認(rèn)參數(shù)應(yīng)用舉例。voidmain()93四、靜態(tài)成員靜態(tài)成員可以實(shí)現(xiàn)多個(gè)對象之間的數(shù)據(jù)共享,并且使用靜態(tài)成員還不會破壞隱藏的原則,保證了安全性。靜態(tài)數(shù)據(jù)成員靜態(tài)成員函數(shù)四、靜態(tài)成員靜態(tài)成員可以實(shí)現(xiàn)多個(gè)對象之間的數(shù)據(jù)共享,并且使941.靜態(tài)數(shù)據(jù)成員靜態(tài)數(shù)據(jù)成員是類的所有對象中共享的成員,而不是某個(gè)對象的成員。彌補(bǔ)了全局變量的不足,它相對于類中的“全局變量”。注意:靜態(tài)成員所占空間不會隨著對象的產(chǎn)生而分配,隨著對象的消失而回收。1.靜態(tài)數(shù)據(jù)成員靜態(tài)數(shù)據(jù)成員是類的所有對象中共享的成員,而95例7.8問題:靜態(tài)數(shù)據(jù)成員定義。#include<iostream>usingnamespacestd;classtime{public:time(int,int);voiddisplay();private: staticinthour;//hour是一個(gè)靜態(tài)數(shù)據(jù)成員。intminute;intsecond;};例7.8問題:靜態(tài)數(shù)據(jù)成員定義。#include<ios96例7.8問題:靜態(tài)數(shù)據(jù)成員定義。time::time(intm,ints):minute(m),second(s){};inttime::hour=15;voidtime::display(){cout<<hour<<":"<<minute<<":"<<second<<endl;}voidmain(){timet1(06,20),t2(10,30);t1.display();t2.display();}該程序的運(yùn)行結(jié)果為:15:6:2015:10:30例7.8問題:靜態(tài)數(shù)據(jù)成員定義。time::time(in97說明:靜態(tài)數(shù)據(jù)成員的初始化應(yīng)在類體外進(jìn)行,其格式如下:<數(shù)據(jù)類型><類名>::<靜態(tài)數(shù)據(jù)成員名>=<初值>例如,inttime::hour=15;在數(shù)據(jù)成員前不加static,而應(yīng)使用作用域運(yùn)算符來表明所屬類。在程序中如果靜態(tài)數(shù)據(jù)成員的訪問權(quán)限為公有(public)成員,則可按如下格式引用:<類名>::<靜態(tài)成員名>//前面直接用類名靜態(tài)數(shù)據(jù)成員被存放在靜態(tài)存儲區(qū)。說明:靜態(tài)數(shù)據(jù)成員的初始化應(yīng)在類體外進(jìn)行,其格式如下:982.靜態(tài)成員函數(shù)在靜態(tài)成員函數(shù)的實(shí)現(xiàn)中,可以直接引用靜態(tài)成員,但不能直接引用非靜態(tài)成員,如果要引用非靜態(tài)成員時(shí),可通過對象來引用。對靜態(tài)成員函數(shù)的引用,在程序中一般使用下列格式:類名.靜態(tài)成員函數(shù)(參數(shù)表)有時(shí),也可以由對象來引用,格式如下:對象.靜態(tài)成員函數(shù)(參數(shù)表)2.靜態(tài)成員函數(shù)在靜態(tài)成員函數(shù)的實(shí)現(xiàn)中,可以直接引用靜態(tài)成99例7.9問題:靜態(tài)成員函數(shù)對非靜態(tài)成員的引用。#include<iostream.h>classtest{public:test(inta){A=a;B+=a;}

staticvoidf(testm);

//靜態(tài)公有成員函數(shù)聲明private:

intA;

staticintB;//靜態(tài)私有成員};例7.9問題:靜態(tài)成員函數(shù)對非靜態(tài)成員的引用。#inclu100例7.9問題:靜態(tài)成員函數(shù)對非靜態(tài)成員的引用。inttest::B=0;//靜態(tài)成員初始化voidtest::f(testm){cout<<"A="<<m.A<<endl;//引用類的非靜態(tài)成員,用對象引用cout<<"B="<<B<<endl;//引用類的靜態(tài)成員,直接引用}voidmain(){testX(10),Y(20);test::f(X);//調(diào)用靜態(tài)成員函數(shù)test::f(Y);//調(diào)用靜態(tài)成員函數(shù)}該程序的運(yùn)行結(jié)果為:例7.9問題:靜態(tài)成員函數(shù)對非靜態(tài)成員的引用。intte101靜態(tài)成員函數(shù)的使用注意:只能訪問類的靜態(tài)數(shù)據(jù)成員,而不能直接訪問類中的普通成員(需用點(diǎn)域法)靜態(tài)成員函數(shù)與類相聯(lián)系,而不與類的對象相聯(lián)系,所以在類的外部調(diào)用類中的公有靜態(tài)成員函數(shù),必須在其左面加"類名::",而不是通過對象名調(diào)用公有靜態(tài)成員函數(shù)。在類的外部不能調(diào)用類中的私有靜態(tài)成員函數(shù)。靜態(tài)成員函數(shù)的使用注意:只能訪問類的靜態(tài)數(shù)據(jù)成員,而不能直接102五、友元為了方便類內(nèi)數(shù)據(jù)的訪問,提出友元方案。兩種形式友元函數(shù)友元類特點(diǎn):破壞了類的封閉性和隱藏性,但是提高了程序的運(yùn)行效率。五、友元為了方便類內(nèi)數(shù)據(jù)的訪問,提出友元方案。1031.友元函數(shù)友元函數(shù)是定義在類外部的普通函數(shù),但對它的說明是在類內(nèi)部,在友元函數(shù)的說明前加關(guān)鍵字friend。友元函數(shù)說明格式:friend類型友元函數(shù)名(參數(shù)表);在類外定義友元函數(shù)的格式:類型函數(shù)名(類&對象);注意:友元函數(shù)不是成員函數(shù),但可以訪問類中的私有成員。聲明可在私有部分,也可在公有部分,作用相同。友元函數(shù)的調(diào)用方式于普通函數(shù)相同。1.友元函數(shù)友元函數(shù)是定義在類外部的普通函數(shù),但對它的說明是104Private:成員……public:pubf();……f()外部函數(shù)間接訪問Private:成員……public:pubf();friendf();……f()友元函數(shù)指定友元關(guān)系直接訪問無友元關(guān)系有友元關(guān)系友元函數(shù)關(guān)系示意圖Private:f()外部函數(shù)間接訪問

溫馨提示

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

評論

0/150

提交評論