《CC++語言程序設(shè)計(jì)》課件第10章 類和對(duì)象_第1頁
《CC++語言程序設(shè)計(jì)》課件第10章 類和對(duì)象_第2頁
《CC++語言程序設(shè)計(jì)》課件第10章 類和對(duì)象_第3頁
《CC++語言程序設(shè)計(jì)》課件第10章 類和對(duì)象_第4頁
《CC++語言程序設(shè)計(jì)》課件第10章 類和對(duì)象_第5頁
已閱讀5頁,還剩92頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第十章類和對(duì)象10.1類與對(duì)象的基本概念10.2構(gòu)造函數(shù)和析構(gòu)函數(shù)10.3靜態(tài)成員10.4類對(duì)象作為成員10.5友元10.6小結(jié)10.1類與對(duì)象的基本概念對(duì)象具有以下特性:(1)每一個(gè)對(duì)象必須有一個(gè)名字以區(qū)別于其它對(duì)象;(2)用屬性(或叫狀態(tài))來描述它的某些特征;(3)有一組操作,每一個(gè)操作決定對(duì)象的一種行為。類是對(duì)具有共同屬性特征與行為特征的對(duì)象的抽象。10.1.1類的聲明類定義的一般形式如下:

如果未指定類成員的訪問權(quán)限,默認(rèn)訪問權(quán)限是私有的,且數(shù)據(jù)成員和成員函數(shù)出現(xiàn)的順序也沒有關(guān)聯(lián)。class類名{[private:]

私有的數(shù)據(jù)成員和成員函數(shù)public:

公有的數(shù)據(jù)成員和成員函數(shù)};【例10.1】定義二維坐標(biāo)點(diǎn)Point類classPoint{private:intxVal,yVal;public:intGetX();intGetY();voidSetPt(int,int);voidOffsetPt(int,int);};說明:(1)類聲明中的private和public兩個(gè)關(guān)鍵字可以按任意順序出現(xiàn)任意次。但是,如果把所有的私有成員和公有成員函數(shù)歸類放在一起,程序?qū)⒏忧逦#?)除了private和public之外,類中的成員還能被另一個(gè)關(guān)鍵字protected來說明。被protected說明的成員成為保護(hù)成員。保護(hù)成員只能被該類的成員函數(shù)或派生類的成員函數(shù)訪問,有關(guān)基類和派生類的概念我們?cè)谙乱徽陆榻B。(3)數(shù)據(jù)成員可以是任何數(shù)據(jù)類型,但是不能用自動(dòng)(auto)、寄存器(register)或外部(extern)進(jìn)行說明。(4)不能在類的聲明中給數(shù)據(jù)成員賦初值,例如:classA{private:intx=1;//錯(cuò)誤

chary='c';//錯(cuò)誤

public:…};10.1.2類成員函數(shù)的定義成員函數(shù)的定義通常采用兩種方式。第一種方式是在類聲明中只給出成員函數(shù)的原型,而成員函數(shù)體在類的外部定義,一般形式如下:函數(shù)類型類名::函數(shù)名(形參表){

//函數(shù)體}【例10.2】定義Point類的成員函數(shù)intPoint::GetX(){returnxVal;}intPoint::GetY(){returnyVal;}voidPoint::SetPt(intx,inty){

xVal=x;

yVal=y;}voidPoint::OffsetPt(intx,inty){xVal+=x;yVal+=y;}成員函數(shù)的第二種定義方式是:將成員函數(shù)定義在類的內(nèi)部,即定義為內(nèi)置函數(shù)。在C++中,可以用下面兩種格式定義類的內(nèi)置函數(shù):(1)隱式定義:所謂內(nèi)置函數(shù)的隱式定義,就是直接將函數(shù)定義在類內(nèi)部,例如:classPoint{ intxVal,yVal;public: intGetX() {returnxVal;} intGetY() {returnyVal;} voidSetPt(intx,inty) {xVal=x;yVal=y;} voidOffsetPt(intx,inty) {xVal+=x;yVal+=y;}};(2)顯式定義:定義內(nèi)置函數(shù)時(shí),將它放在類定義體外,但在該成員函數(shù)定義前插入inline關(guān)鍵字,使它仍然起內(nèi)置函數(shù)的作用。inlineintPoint::GetX(){returnxVal;}inlineintPoint::GetY(){returnyVal;}inlinevoidPoint::SetPt(intx,inty){

xVal=x;

yVal=y;}inlinevoidPoint::OffsetPt(intx,inty){xVal+=x;yVal+=y;}10.1.3對(duì)象的定義與引用定義了類以后,就可以定義其類型的變量,C++類的變量稱為類的對(duì)象,對(duì)象也稱為類的實(shí)例。1.對(duì)象的定義(1)在聲明類的同時(shí),直接定義對(duì)象,就是在聲明類的右花括號(hào)“}”后,直接寫出屬于該類的對(duì)象名表。例如classPoint{private:intxVal,yVal;public:intGetX();intGetY();voidSetPt(int,int);voidOffsetPt(int,int);}op1,op2;(2)先聲明類,在使用時(shí)再定義對(duì)象。定義的格式與一般變量的定義格式相同,如下所示:Pointop1,op2;此時(shí)定義了Point類的兩個(gè)對(duì)象op1和op2。值得注意的是,聲明了一個(gè)類相當(dāng)于聲明了一種類型,它并不接收和存取具體的值,只有定義了對(duì)象后,系統(tǒng)才為對(duì)象并且只為對(duì)象分配存儲(chǔ)空間。2.對(duì)象的引用對(duì)象的引用是指對(duì)對(duì)象成員的引用。不論是數(shù)據(jù)成員還是成員函數(shù),只要是公有的,就可以被外部函數(shù)直接引用。引用的格式是:對(duì)象名.數(shù)據(jù)成員名或?qū)ο竺?成員函數(shù)名(實(shí)參表)【例10.3】定義Point類的對(duì)象#include<iostream.h>classPoint{ intxVal,yVal;public: intGetX() {returnxVal;} intGetY() {returnyVal;} voidSetPt(intx,inty) {xVal=x;yVal=y;} voidOffsetPt(intx,inty) {xVal+=x;yVal+=y;}};voidmain(){ Pointop1; inti,j; op1.SetPt(1,2); //調(diào)用op1的SetPt(),初始化對(duì)象op1 i=op1.GetX(); //調(diào)用op1的GetX(),取op1的xVal值

j=op1.GetY(); //調(diào)用op1的Gety(),取op1的yVal值

cout<<"op1i="<<i<<"op1j="<<j<<endl; op1.OffsetPt(3,4);

//調(diào)用op1的OffsetPt(),改變op1的xVal和yVal值

i=op1.GetX(); //調(diào)用op1的GetX(),取op1的xVal值

j=op1.GetY(); //調(diào)用op1的Gety(),取op1的yVal值

cout<<"op1i="<<i<<"op1j="<<j<<endl;}(1)本例中op1.SetPt(1,2)實(shí)際上是一種縮寫形式,它表達(dá)的意義是op1.Point::SetPt(1,2),這兩種表達(dá)式是等價(jià)的。(2)外部函數(shù)不能引用對(duì)象的私有成員voidmain(){ Pointop1; inti,j; op1.SetPt(1,2); i=op1.xVal; //錯(cuò)誤

j=op1.yVal; //錯(cuò)誤

cout<<"op1i="<<i<<"op1j="<<j<<endl;}(3)在定義對(duì)象時(shí),若我們定義的是指向此對(duì)象的指針,則訪問此對(duì)象的成員時(shí),不能用“.”調(diào)用符,而應(yīng)使用“->”操作符,例如:voidmain(){ Point*op; op->SetPt(1,2); //…}3.對(duì)象賦值語句同類型的對(duì)象之間也可以進(jìn)行賦值,當(dāng)一個(gè)對(duì)象賦值給另一個(gè)對(duì)象時(shí),所有的數(shù)據(jù)成員都會(huì)逐位復(fù)制?!纠?0.4】對(duì)象賦值#include<iostream.h>classPoint{ intxVal,yVal;public: voidSetPt(intx,inty) {xVal=x;yVal=y;} voidshow() {cout<<xVal<<""<<yVal<<endl;}};voidmain(){ Pointop1,op2; op1.SetPt(1,2); op2=op1; //將對(duì)象op1的值賦給op2 op1.show();op2.show();}說明:(1)在使用對(duì)象賦值語句進(jìn)行對(duì)象賦值時(shí),兩個(gè)對(duì)象的類型必須相同,若對(duì)象的類型不同,編譯時(shí)將出錯(cuò)。(2)兩個(gè)對(duì)象之間的賦值,僅僅使這些對(duì)象中數(shù)據(jù)相同,而兩個(gè)對(duì)象仍然是分離的。例如本例對(duì)象賦值后,再調(diào)用op1.SetPt()設(shè)置op1的值,不會(huì)影響op2的值。(3)當(dāng)類中存在指針時(shí),將一個(gè)對(duì)象的值賦給另一個(gè)對(duì)象時(shí),可能會(huì)產(chǎn)生錯(cuò)誤。10.1.4對(duì)象數(shù)組對(duì)象數(shù)組是指每一數(shù)組元素都是對(duì)象的數(shù)組,也就是說,若一個(gè)類有若干個(gè)對(duì)象,我們把這一系列的對(duì)象用一個(gè)數(shù)組來存放。下面是一個(gè)對(duì)象數(shù)組的例子?!纠?0.5】定義類Point的對(duì)象數(shù)組#include<iostream.h>classPoint{ intxVal,yVal;public: voidSetPt(intx,inty) {xVal=x;yVal=y;} voidshow() {cout<<xVal<<""<<yVal<<endl;}};voidmain(){ Pointop[4];inti; for(i=0;i<4;i++) op[i].SetPt(i,i); for(i=0;i<4;i++) op[i].show();}10.1.5對(duì)象指針我們知道,在C語言中能夠直接訪問結(jié)構(gòu),或通過指向該結(jié)構(gòu)的指針來訪問結(jié)構(gòu)。類似地,在C++語言中可以直接引用對(duì)象,也可以通過指向該對(duì)象的指針引用對(duì)象。對(duì)象指針是C++的重要特性之一。1.用指針引用對(duì)象成員一般情況下,用點(diǎn)運(yùn)算符“.”來引用對(duì)象成員,當(dāng)用指向?qū)ο蟮闹羔榿硪脤?duì)象成員時(shí),就要用“->”操作符?!纠?0.6】對(duì)象指針的使用。#include<iostream.h>classPoint{ intxVal,yVal;public: voidSetPt(intx,inty) {xVal=x;yVal=y;} voidshow() {cout<<xVal<<""<<yVal<<endl;}};voidmain(){Pointop,*p; //聲明類Point的對(duì)象op和對(duì)象指針pop.SetPt(1,2); op.show();p=&op; //將p指針指向?qū)ο髈pp->show(); }2.用對(duì)象指針引用對(duì)象數(shù)組下面我們來介紹用對(duì)象指針引用對(duì)象數(shù)組的情況。對(duì)象指針不僅能引用單個(gè)對(duì)象,也能引用對(duì)象數(shù)組。下面的語句聲明了一個(gè)對(duì)象指針和一個(gè)有兩個(gè)元素的對(duì)象數(shù)組:Point*p;Pointop[2];若只有數(shù)組名,沒有下標(biāo),這時(shí)該數(shù)組名代表第一個(gè)元素的地址,所以執(zhí)行語句:p=op;就把對(duì)象數(shù)組的第一個(gè)元素的地址賦給對(duì)象指針p。voidmain(){Pointop[2],*p; //聲明類Point的對(duì)象數(shù)組op[2]和對(duì)象指針pop[0].SetPt(1,2);op[1].SetPt(3,4); p=op; //將p指針指向?qū)ο髷?shù)組op的第一個(gè)元素

p->show(); p++;//將p指針指向?qū)ο髷?shù)組op的第二個(gè)元素

p->show(); }3.this指針C++中,定義了一個(gè)this指針,它是成員函數(shù)所屬對(duì)象的指針。它指向類對(duì)象的地址,成員函數(shù)通過這個(gè)指針可以知道自己屬于哪一個(gè)對(duì)象。this指針是一種隱含指針,它隱含于每個(gè)類的成員函數(shù)中,僅能在類的成員函數(shù)中訪問。因此,成員函數(shù)訪問類中數(shù)據(jù)成員的格式可以寫成:this->成員變量classDate{private: intyear; intmonth; intday;public: voidsetYear(int); voidsetMonth(int); voidsetDay(int);}該類的成員函數(shù)setMonth,可用兩種方法實(shí)現(xiàn):voidDate::setMonth(intmn)//使用隱含的this指針{

month=mn;}voidDate::setMonth(intmn)//顯式使用this指針{

this->month=mn;}雖然顯式使用this指針的情況并不是很多,但是,this指針有時(shí)是有用的。例如,下面的賦值是不允許的:voidDate::setMonth(intmonth){

month=month;}但可以用this指針來解決:voidDate::setMonth(intmonth){

this->month=month;}【例10.7】this指針示例。#include<iostream.h>classsample{ inti;public: voidload(intval) {this->i=val;} intget() {returnthis->i;}};voidmain(){ sampleobj; obj.load(10); cout<<obj.get();}10.1.6const在類中的應(yīng)用1.const成員變量用const修飾的成員變量稱為const的成員變量。使用時(shí)應(yīng)注意const成員變量只能在構(gòu)造函數(shù)里使用初始化成員列表來初始化,試圖在構(gòu)造函數(shù)體內(nèi)進(jìn)行初始化會(huì)引起編譯錯(cuò)誤。初始化成員列表形如:classX{ constintr;//const成員變量public: X(inta):r(a)//初始化成員列表 {} //...};2.const成員函數(shù)const成員函數(shù)指的是const放在成員函數(shù)后面,形如:voidfun()const;表明這個(gè)函數(shù)不會(huì)對(duì)這個(gè)類對(duì)象的非靜態(tài)數(shù)據(jù)成員作任何改變,不能在const成員函數(shù)中調(diào)用其他非const的成員函數(shù)。例如:classStack{public:voidPush(intelem);intPop();intGetCount()const;//const成員函數(shù)private:intm_num;intm_data[100];};intStack::GetCount()const{++m_num;

//編譯錯(cuò)誤,企圖修改數(shù)據(jù)成員m_num

Pop();//編譯錯(cuò)誤,企圖調(diào)用非const成員函數(shù)returnm_num;}任何不會(huì)修改數(shù)據(jù)成員的成員函數(shù)都應(yīng)該聲明為const類型。如果在編寫const成員函數(shù)時(shí),不慎修改了數(shù)據(jù)成員,或者調(diào)用了其他非const成員函數(shù),編譯器將報(bào)錯(cuò),這極大的提高了程序的健壯性。建立了一個(gè)const成員函數(shù),但仍然想用這個(gè)函數(shù)改變對(duì)象內(nèi)部的數(shù)據(jù)。有三種方法可以實(shí)現(xiàn),一是使用類型強(qiáng)制轉(zhuǎn)換方法。例如:classX{ intr;public: X(inta) {r=a;} voidf()const {((X*)this)->r++;}

//通過this指針進(jìn)行類型強(qiáng)制轉(zhuǎn)換實(shí)現(xiàn) //...};其二是采用const_cast運(yùn)算符去掉this指針的const屬性,例如:classX{ intr;public: X(inta) {r=a;} voidf()const {(const_cast<X*>(this))->r++;}//通過const_cast運(yùn)算符去掉this指針的const屬性 //...};其中const_cast運(yùn)算符的用法是:

const_cast<類型>(表達(dá)式)const_cast運(yùn)算符可以去掉一個(gè)類的const,volatile,和_unaligned屬性。第三種方法就是使用關(guān)鍵字:mutable。關(guān)鍵字mutable可以把一個(gè)成員定義為可變動(dòng)的,也就是被mutable定義的成員是可以被const成員函數(shù)修改的。例如:#include<iostream.h>classConstFunc{public: ConstFunc() {i=j=1;} voidFun()const; voidshow()const;private: inti; mutableintj;//聲明了一個(gè)mutable成員變量};voidConstFunc::Fun()const{ i++;//非法,不能改變i的值 j++;//合法,可以改變用//mutable聲明的成員變量}voidConstFunc::show()const{cout<<"i="<<i<<",j="<<j<<endl;}3.const對(duì)象同const成員函數(shù)有關(guān)的一個(gè)概念就是const對(duì)象,即在定義對(duì)象時(shí)用const來修飾。const對(duì)象只可以調(diào)用類的const成員函數(shù),而非const對(duì)象可以訪問任意的成員函數(shù),包括const成員函數(shù)。classX{public: X(intm):i(m){} intf()const{ i++; //錯(cuò)誤:不可以在const成員函數(shù)中做改變普通數(shù)//據(jù)成員的操作 returni; } intf2(){ i++; returni; }private: inti;};voidmain(){ Xx1(100); constXx2(200);//聲明一個(gè)const對(duì)象 x1.f();//合法:非const對(duì)象可以調(diào)用

//const成員函數(shù) x2.f();//合法:對(duì)象只能調(diào)用const成員函數(shù) x2.f1();//錯(cuò)誤:const對(duì)象不能調(diào)用

//非const成員函數(shù)}10.2構(gòu)造函數(shù)和析構(gòu)函數(shù)C++中定義了一種特殊的初始化函數(shù),稱之為構(gòu)造函數(shù)。當(dāng)對(duì)象被創(chuàng)建時(shí),構(gòu)造函數(shù)自動(dòng)被調(diào)用。構(gòu)造函數(shù)具有一些特殊的性質(zhì):(1)構(gòu)造函數(shù)的名字必須與類名相同。(2)構(gòu)造函數(shù)可以有任意類型的參數(shù),但不能具有返回類型。(3)定義對(duì)象時(shí),編譯系統(tǒng)會(huì)自動(dòng)地調(diào)用構(gòu)造函數(shù)。10.2.1構(gòu)造函數(shù)【例10.8】為類Point定義構(gòu)造函數(shù)classPoint{ intxVal,yVal;public: Point(intx,inty) {xVal=x;yVal=y;} voidshow() {cout<<xVal<<""<<yVal<<endl;}};構(gòu)造函數(shù)不能像其他成員函數(shù)那樣被顯式地調(diào)用,它是在定義對(duì)象的同時(shí)調(diào)用的,其一般格式為:類名對(duì)象名(實(shí)參表);現(xiàn)在,我們可以定義Point類對(duì)象并立即初始化它們:Pointpt1(10,20);//xVal和yVal的初值分別為10和20說明:(1)構(gòu)造函數(shù)沒有返回值,在聲明和定義構(gòu)造函數(shù)時(shí),是不能說明它的類型的,甚至說明為void類型也不行。(2)在實(shí)際應(yīng)用中,通常需要給每個(gè)類定義構(gòu)造函數(shù)。如果沒有給類定義構(gòu)造函數(shù),則編譯系統(tǒng)自動(dòng)地生成一個(gè)缺省的構(gòu)造函數(shù)。(3)構(gòu)造函數(shù)可以是不帶參數(shù)的,例如:classabc{private:inta;public:abc(){ cout<<"initialized"<<endl; a=5;}};

(4)構(gòu)造函數(shù)也可以采用構(gòu)造初始化表對(duì)數(shù)據(jù)成員進(jìn)行初始化classA{ inti; charj; floatf;public: A(intx,chary,floatz):i(x),j(y),f(z) {}};

但是如果需要將數(shù)據(jù)成員放在堆中或數(shù)組中,則應(yīng)在構(gòu)造函數(shù)中使用賦值語句,即使構(gòu)造函數(shù)有初始化表也應(yīng)如此,例如:classA{ inti; charj; floatf; charname[25];public: A(intx,chary,floatz,charN[]):i(x),j(y),f(z) {strcpy(name,N);}};(5)對(duì)沒有定義構(gòu)造函數(shù)的類,其公有數(shù)據(jù)成員可以用初始值表進(jìn)行初始化。#include<iostream.h>classmyclass{public: charname[10]; intnumber;};voidmain(){ myclassa={"Jia",1}; cout<<<<""<<a.number<<endl;}10.2.2缺省參數(shù)的構(gòu)造函數(shù)在實(shí)際使用中,有些構(gòu)造函數(shù)的參數(shù)值通常是不變的,只有在特殊情況下才需要改變它的參數(shù)值。這時(shí)可以將其定義成帶缺省參數(shù)的構(gòu)造函數(shù),例如:#include<iostream.h>classPoint{ intxVal,yVal;public: Point(intx=0,inty=0) {xVal=x;yVal=y;} voidshow() {cout<<xVal<<""<<yVal<<endl;}};voidmain(){ Pointp1;//不傳遞參數(shù),全部使用缺省值

Pointp2(2);//只傳遞一個(gè)參數(shù)

Pointp3(2,3);//傳遞兩個(gè)參數(shù)}10.2.3重載構(gòu)造函數(shù)C++允許重載構(gòu)造函數(shù),這些構(gòu)造函數(shù)之間以它們所帶參數(shù)的個(gè)數(shù)和類型的不同而區(qū)分。例10.10重載Point類的構(gòu)造函數(shù)。classPoint{

intxVal,yVal;

public:

Point(intx,inty)//笛卡兒坐標(biāo)

{xVal=x;yVal=y;}

Point(floatlen,floatangle)//極坐標(biāo)

{

xVal=(int)(len*cos(angle));

yVal=(int)(len*sin(angle));

}

Point()//原點(diǎn)

{xVal=yVal=0;}//…};voidmain(){

Pointpt1(10,20); //笛卡兒坐標(biāo)

Pointpt2(60.3,10.14); //極坐標(biāo)

Pointpt3; //原點(diǎn)

//…}【例10.11】計(jì)時(shí)器程序。#include<iostream.h>#include<stdlib.h>classtimer{ intseconds;public: timer() {seconds=0;} timer(char*t) {seconds=atoi(t);} timer(intt) {seconds=t;} timer(intmin,intsec) {seconds=min*60+sec;} intgettime() {returnseconds;}};voidmain(){ timera,b(10),c("30"),d(1,20); cout<<"seconds1="<<a.gettime()<<endl; cout<<"seconds2="<<b.gettime()<<endl; cout<<"seconds3="<<c.gettime()<<endl; cout<<"seconds4="<<d.gettime()<<endl;}說明:在重載沒有參數(shù)和帶缺省參數(shù)的構(gòu)造函數(shù)時(shí),有可能產(chǎn)生二義性,例如:classA{public: A(); A(inti=0);};voidmain(){ Aa1(10);//正確

Aa2;//存在二義性

//...}10.2.4復(fù)制構(gòu)造函數(shù)復(fù)制構(gòu)造函數(shù)是一種特殊的構(gòu)造函數(shù)。它用于依據(jù)已存在的對(duì)象建立一個(gè)新對(duì)象。用戶可以根據(jù)自己的需要定義復(fù)制構(gòu)造函數(shù),系統(tǒng)也可以為類產(chǎn)生一個(gè)缺省的復(fù)制構(gòu)造函數(shù)。1.自定義復(fù)制構(gòu)造函數(shù)自定義復(fù)制構(gòu)造函數(shù)的一般形式如下:其中,ob是用來初始化的另一個(gè)對(duì)象的引用。classname(constclassname&ob){//復(fù)制構(gòu)造函數(shù)的函數(shù)體}classPoint{intxVal,yVal;public:Point(intx,inty){xVal=x;yVal=y;}//構(gòu)造函數(shù)

Point(constPoint&p)//復(fù)制構(gòu)造函數(shù) {xVal=2*p.xVal;yVal=2+p.yVal;} //...};例10.12自定義Point類復(fù)制構(gòu)造函數(shù)#include<iostream.h>classPoint{intxVal,yVal;public:Point(intx,inty){xVal=x;yVal=y;}//構(gòu)造函數(shù)

Point(constPoint&p)//復(fù)制構(gòu)造函數(shù) {xVal=2*p.xVal;yVal=2*p.yVal;} voidprint() {cout<<xVal<<""<<yVal<<endl;}};voidmain(){ Pointp1(30,40);//定義類Point的對(duì)象p1 Pointp2(p1);//顯示調(diào)用復(fù)制構(gòu)造函數(shù)//創(chuàng)建對(duì)象p2 p1.print(); p2.print();}例中除了顯式調(diào)用復(fù)制構(gòu)造函數(shù)外,還可以采用賦值形式調(diào)用復(fù)制構(gòu)造函數(shù)。若將主函數(shù)main()改寫成如下形式:voidmain(){ Pointp1(30,40); Pointp2=p1;//使用賦值形式調(diào)用

//復(fù)制構(gòu)造函數(shù),創(chuàng)建對(duì)象p2 p1.print(); p2.print();}2.缺省的復(fù)制構(gòu)造函數(shù)如果沒有編寫自定義的復(fù)制構(gòu)造函數(shù),在用已存在對(duì)象建立新對(duì)象時(shí),C++會(huì)自動(dòng)地將已存在的對(duì)象賦值給新對(duì)象,這種按成員逐一復(fù)制的過程是由缺省復(fù)制構(gòu)造函數(shù)自動(dòng)完成的。例10.13例10.12中去掉自定義的復(fù)制構(gòu)造函數(shù)。#include<iostream.h>classPoint{intxVal,yVal;public:Point(intx,inty){xVal=x;yVal=y;}//構(gòu)造函數(shù)

voidprint(){cout<<xVal<<""<<yVal<<endl;} };voidmain(){ Pointp1(30,40);//定義類Point的對(duì)象p1 Pointp2(p1);

//顯示調(diào)用復(fù)制構(gòu)造函數(shù),創(chuàng)建對(duì)象p2 Pointp3=p1;//使用賦值形式調(diào)用復(fù)制構(gòu)造函數(shù),創(chuàng)建對(duì)象p3 p1.print(); p2.print(); p3.print();}程序的運(yùn)行結(jié)果為:30403040304010.2.5析構(gòu)函數(shù)當(dāng)對(duì)象銷毀時(shí),也會(huì)自動(dòng)調(diào)用析構(gòu)函數(shù)進(jìn)行一些清理工作以釋放內(nèi)存。與構(gòu)造函數(shù)類似的是:析構(gòu)函數(shù)也與類同名,但在類名前有一個(gè)“~”符號(hào)。析構(gòu)函數(shù)也沒有返回類型和返回值,但析構(gòu)函數(shù)不帶參數(shù),不能重載,所以析構(gòu)函數(shù)只有一個(gè)。如果在一個(gè)對(duì)象完成其操作之前需要做一些內(nèi)部處理如釋放內(nèi)存空間,則應(yīng)該顯式的定義析構(gòu)函數(shù),例如:classmystring{ char*str;public: mystring(char*s) { str=newchar[strlen(s)+1]; strcpy(str,s); } ~mystring() {deletestr;} voidget_str(char*); voidsent_str(char*);};10.2.6動(dòng)態(tài)對(duì)象創(chuàng)建一個(gè)對(duì)象被動(dòng)態(tài)創(chuàng)建時(shí),依次發(fā)生兩件事情:(1)為對(duì)象分配內(nèi)存空間;(2)調(diào)用構(gòu)造函數(shù)來初始化這塊內(nèi)存。同樣,一個(gè)對(duì)象被動(dòng)態(tài)銷毀時(shí),按照順序發(fā)生了下面兩件事情:(1)調(diào)用析構(gòu)函數(shù)清除對(duì)象;(2)釋放對(duì)象的內(nèi)存空間?!纠?0.14】用new和delete動(dòng)態(tài)創(chuàng)建和銷毀對(duì)象。#include<iostream.h>classTree{private:

intheight;public:

Tree(intheight)

{

cout<<"treeobjectiscreating"<<endl;

this->height=height;

}~Tree()

{

cout<<"treeobjectisdeleting"<<endl;

}

voiddisplay()

{

cout<<"thistreeis"<<height<<"metershigh"<<endl;

}};voidmain(){

Tree*tree=newTree(100);

tree->display();

deletetree;}程序的運(yùn)行結(jié)果為:treeobjectiscreatingthistreeis100metershightreeobjectisdeleting注意:構(gòu)造函數(shù)是在對(duì)象創(chuàng)建時(shí)被調(diào)用,對(duì)象何時(shí)創(chuàng)建與對(duì)象的作用域有關(guān)。例如,全局對(duì)象是在程序開始執(zhí)行時(shí)創(chuàng)建,自動(dòng)對(duì)象是當(dāng)進(jìn)入其作用域時(shí)創(chuàng)建,動(dòng)態(tài)對(duì)象則是在使用new運(yùn)算符時(shí)創(chuàng)建。10.3靜態(tài)成員類對(duì)象的公有或私有的數(shù)據(jù)成員,可被該類的每一個(gè)public或private函數(shù)訪問。有時(shí),可能需要一個(gè)或多個(gè)公共的數(shù)據(jù)成員,能夠被類的所有對(duì)象共享,這類數(shù)據(jù)成員稱為靜態(tài)成員。在C++中,可以定義靜態(tài)的數(shù)據(jù)成員和成員函數(shù)。10.3.1靜態(tài)數(shù)據(jù)成員定義靜態(tài)數(shù)據(jù)成員,只需在數(shù)據(jù)成員的定義前增加static關(guān)鍵字。靜態(tài)數(shù)據(jù)成員不同于非靜態(tài)的數(shù)據(jù)成員,一個(gè)類的靜態(tài)數(shù)據(jù)成員僅創(chuàng)建和初始化一次,且在程序開始執(zhí)行的時(shí)候創(chuàng)建,然后被該類的所有對(duì)象共享;而非靜態(tài)的數(shù)據(jù)成員則隨著對(duì)象的創(chuàng)建而多次創(chuàng)建和初始化。例10.15靜態(tài)數(shù)據(jù)成員應(yīng)用實(shí)例。說明:(1)靜態(tài)數(shù)據(jù)成員屬于類(準(zhǔn)確地說,是屬于類中的一個(gè)對(duì)象集合),而不像普通數(shù)據(jù)成員那樣屬于某一個(gè)對(duì)象,因此可以使用“類名::”訪問靜態(tài)的數(shù)據(jù)成員。(2)靜態(tài)數(shù)據(jù)成員不能在類中進(jìn)行初始化,因?yàn)樵陬愔胁唤o它分配內(nèi)存空間,必須在類外的其他地方為它提供定義。一般在main()開始之前,類的聲明之后的特殊地帶為它提供定義和初始化。缺省時(shí),靜態(tài)成員被初始化為零。(3)靜態(tài)數(shù)據(jù)成員與靜態(tài)變量一樣,是在編譯時(shí)創(chuàng)建并初始化。它在類的任何對(duì)象被建立之前就存在,它可以在程序內(nèi)部不依賴于任何對(duì)象被訪問。(4)靜態(tài)數(shù)據(jù)成員的主要用途是定義類的各個(gè)對(duì)象所公用的數(shù)據(jù),如統(tǒng)計(jì)總數(shù)、平均數(shù)等。例10.16不引用任何特定的對(duì)象,將靜態(tài)數(shù)據(jù)成員的值置為200。C++支持靜態(tài)數(shù)據(jù)成員,其主要原因是可以不必使用全局變量。因?yàn)橐蕾囉谌肿兞康念悗缀醵际沁`反面向?qū)ο蟪绦蛟O(shè)計(jì)的封裝原理的。10.3.2靜態(tài)成員函數(shù)同靜態(tài)數(shù)據(jù)成員類似,定義靜態(tài)成員函數(shù),只需在成員函數(shù)的定義前增加static關(guān)鍵字。靜態(tài)成員函數(shù)屬于整個(gè)類,是該類所有對(duì)象共享的成員函數(shù),而不屬于類中的某個(gè)對(duì)象。注意:靜態(tài)成員函數(shù)僅能訪問靜態(tài)的數(shù)據(jù)成員,不能訪問非靜態(tài)的數(shù)據(jù)成員,也不能訪問非靜態(tài)的成員函數(shù)。這是由于靜態(tài)的成員函數(shù)沒有this指針。類似于靜態(tài)的數(shù)據(jù)成員,公有的、靜態(tài)的成員函數(shù)在類外的調(diào)用方式為:類名::靜態(tài)成員函數(shù)名(實(shí)參表)C++允許用對(duì)象調(diào)用靜態(tài)的成員函數(shù)。例10.17調(diào)用靜態(tài)成員函數(shù)的方法。10.4類對(duì)象作為成員在類定義中定義的數(shù)據(jù)成員一般都是基本的數(shù)據(jù)類型。但是類中的成員也可以是對(duì)象,稱為對(duì)象成員。使用對(duì)象成員要注意的問題是構(gòu)造函數(shù)的定義方式,即類內(nèi)部對(duì)象的初始化問題。凡有對(duì)象成員的類,即構(gòu)造函數(shù)和不含對(duì)象成員的構(gòu)造函數(shù)有所不同,例如有以下的類:classX{

類名1成員名1

類名2成員名2…

類名n成員名n};一般來說,類X的構(gòu)造函數(shù)的定義形式為:X::X(參數(shù)表0):成員名1(參數(shù)表1),…,成員名n(參數(shù)表n){//構(gòu)造函數(shù)體}【例10.18】將string類對(duì)象作為Student類成員。#include<iostream.h>#include<string.h>classstring{ char*str;public: string(char*s) { str=newchar[strlen(s)+1]; strcpy(str,s); } voidprint() {cout<<str<<endl;} ~string() {deletestr;}};classStudent{ stringname;//name為類Student的對(duì)象成員

intage;public: Student(char*st,intag):name(st)//定義類Student的構(gòu)造函數(shù)

{ age=ag; } voidprint() { name.print(); cout<<"age:"<<age<<endl; } };voidmain(){ Studentg("Liuli",18); g.print();}說明:(1)聲明一個(gè)含有對(duì)象成員的類,首先要?jiǎng)?chuàng)建各成員對(duì)象。本例在聲明類Student中,定義了對(duì)象成員name:stringname;(2)Student類對(duì)象在調(diào)用構(gòu)造函數(shù)進(jìn)行初始化時(shí),也要為對(duì)象成員進(jìn)行初始化,因?yàn)樗彩菍儆诖祟惖某蓡T。因此在寫類Student的構(gòu)造函數(shù)時(shí),也綴上了其對(duì)象成員的初始化:

Student(char*st,intag):name(st)于是,在調(diào)用Student的構(gòu)造函數(shù)進(jìn)行初始化時(shí),也給其對(duì)象成員name賦上了初值。注意:在定義類Student的構(gòu)造函數(shù)時(shí)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(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)論