四、析構(gòu)函數(shù) (destructor)五、賦值運(yùn)算符函數(shù)operator =六、成員_第1頁
四、析構(gòu)函數(shù) (destructor)五、賦值運(yùn)算符函數(shù)operator =六、成員_第2頁
四、析構(gòu)函數(shù) (destructor)五、賦值運(yùn)算符函數(shù)operator =六、成員_第3頁
四、析構(gòu)函數(shù) (destructor)五、賦值運(yùn)算符函數(shù)operator =六、成員_第4頁
四、析構(gòu)函數(shù) (destructor)五、賦值運(yùn)算符函數(shù)operator =六、成員_第5頁
已閱讀5頁,還剩24頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

四、析構(gòu)函數(shù)(destructor)

五、賦值運(yùn)算符函數(shù)operator=

六、成員函數(shù)重載

七、缺省參量的成員函數(shù)

八、編譯器默默提供的成員函數(shù)第15章特殊的成員函數(shù)1四、析構(gòu)函數(shù)(destructor)

析構(gòu)函數(shù)是類中的特殊成員函數(shù)。析構(gòu)函數(shù)與構(gòu)造函數(shù)的作用相反,構(gòu)造函數(shù)在對象的定義點(diǎn)由編譯器自動調(diào)用,析構(gòu)函數(shù)則是在對象生存期結(jié)束時(shí)自動執(zhí)行的成員函數(shù)。 析構(gòu)函數(shù)的語法格式是在無參構(gòu)造函數(shù)的構(gòu)造函數(shù)名前加以一個(gè)波浪符~也即按位求反運(yùn)算符,由此形成特殊的析構(gòu)函數(shù)名,表示“反構(gòu)造函數(shù)”。若沒有提交析構(gòu)函數(shù),編譯器暗中生成一個(gè)公共的缺省析構(gòu)函數(shù),它是空函數(shù)。2析構(gòu)函數(shù)在類中的聲明和定義格式為:

~CType();析構(gòu)函數(shù)名();~類名();//聲明格式CType::~CType()類名::~類名()//定義格式{{

析構(gòu)函數(shù)語句序列;//語句為空時(shí)對應(yīng)缺省的析構(gòu)函數(shù)

}}

上面析構(gòu)函數(shù)的定義放置在實(shí)現(xiàn)文件中,放在類的聲明中時(shí)寫為:

~CType(){語句序列;}~類名(){語句序列;}3構(gòu)造、析構(gòu)函數(shù)和賦值運(yùn)算符函數(shù)都不參入繼承機(jī)制。下面是析構(gòu)函數(shù)的特殊之處:

1).

析構(gòu)函數(shù)是唯一的,既沒有入口參數(shù)也無返回類型,

因此不能重載。

2).

析構(gòu)函數(shù)不能繼承但可以是虛函數(shù)。

3).

析構(gòu)函數(shù)體中不能使用return語句返回值。

4).new運(yùn)算符定義的對象,delete運(yùn)算符清除時(shí)導(dǎo)致析構(gòu)函數(shù)的隱含調(diào)用。4

new運(yùn)算符定義對象時(shí)new運(yùn)算符先申請內(nèi)存然后調(diào)用構(gòu)造函數(shù)。由delete清除new運(yùn)算符定義的對象時(shí),則是先調(diào)用析構(gòu)函數(shù),然后再收回原來由new運(yùn)算符為對象分配的內(nèi)存。

newCType[n]運(yùn)算分配內(nèi)存大小是n*sizeof(CType),并不包含其成員指針其后所間接在構(gòu)造函數(shù)中進(jìn)一步獲得的內(nèi)存,這片內(nèi)存應(yīng)由析構(gòu)函數(shù)先行釋放。

newCType[n]運(yùn)算符與delete[]匹配,newCType運(yùn)算符與delete匹配,其余的搭配都是不穩(wěn)健的,應(yīng)避免。匹配關(guān)系為[CType*pk=newCType[2];..;delete[]pk;]與[CType*p=newCType;...;deletep;]。

delete運(yùn)算符隱含調(diào)用析構(gòu)函數(shù)時(shí),在調(diào)用點(diǎn)相應(yīng)的析構(gòu)函數(shù)應(yīng)是可訪問的。5

[例]

對象定義與析構(gòu)函數(shù)

#include<stdio.h>staticint

numc=0;classCType

{public:CType(int=3);~CType();private:long*m_p;

int

m_n;};

CType::CType(intn){m_n=n;

printf("%d,CType();++%d\n",m_n,++numc);

m_p=newlong[m_n];}

6

CType::~CType(){ printf("%d,~CType();%d--;",m_n,numc--); delete[]m_p;}

CTypeg(1);

CType*q=newCType(9);voidmain()//因此相應(yīng)的析構(gòu)函數(shù)未被調(diào)用

{ printf("Enterintomain(){\n");

CTyped(2);

CType*pk=newCType[2];delete[]pk;

printf("\nGo

outofmain()}\n");}7//程序運(yùn)行輸出結(jié)果:

1,CType();++19,CType();++2Enterintomain(){2,CType();++33,CType();++43,CType();++53,~CType();5--;3,~CType();4--;Gooutofmain()}2,~CType();3--1,~CType();2–8說明:全局對象的構(gòu)造函數(shù)在進(jìn)入主函數(shù)之前就被系統(tǒng)優(yōu)先調(diào)用,這是C++程序相對于C程序一個(gè)重要的突破。析構(gòu)函數(shù)按照與構(gòu)造函數(shù)相反的次序隱含地被系統(tǒng)調(diào)用,最先登陸構(gòu)造的對象最后經(jīng)過析構(gòu)函數(shù)撤離現(xiàn)場。程序5次調(diào)用構(gòu)造函數(shù),4次調(diào)用析構(gòu)函數(shù)。9五、賦值運(yùn)算符函數(shù)operator=

賦值運(yùn)算符函數(shù)也稱為等號運(yùn)算符函數(shù),賦值運(yùn)算符的函數(shù)原型為:

B&B::operator=(constB&r);

函數(shù)原型說明一個(gè)函數(shù)名為operator=的運(yùn)算符函數(shù),B::operator=是這個(gè)函數(shù)的全限定名,表示:operator=函數(shù)是屬于類B的成員函數(shù),圓括號包括的是constB&型的入口形參。

B&是這個(gè)函數(shù)的返回類型,這是一個(gè)返回左值對象的函數(shù)。因此該函數(shù)可以用于連續(xù)的賦值運(yùn)算如a=b=c或(a=b)=c。10[例]

賦值運(yùn)算符函數(shù)與拷貝構(gòu)造函數(shù)

#include<stdio.h>#include<string.h> classB {private:int

m_n; public: B(intv=1){Set(v);} B(constB&r);B&operator=(constB&r);voidSet(int

n){m_n=n;}voidShow(){printf("n=%d;",m_n);}}; B::B(constB&r){printf("callB::B(constB&r);");

memcpy(this,&r,sizeof(B));}11

B&B::operator=(constB&r){printf("callB&B::operator=(constB&r);"); if(this==&r)return*this;

memcpy(this,&r,sizeof(B));return*this;}voidmain(){ Bd;d.Show();Ba=d;a.Show();

a.Set(100);d=a;

d.Show();} //輸出:n=1;callB::B(constB&r);n=1;callB&B::operator=(constB&r);n=10012拷貝構(gòu)造函數(shù)和等號賦值函數(shù)其內(nèi)在機(jī)制是一樣的,memcpy函數(shù)完成幕后數(shù)據(jù)拷貝。等號語法a=d,d=a派生出兩種語義,編譯器根據(jù)周邊氛圍確定調(diào)用合適的函數(shù),在對象的定義點(diǎn)調(diào)用與初始化過程相關(guān)的拷貝構(gòu)造函數(shù),在其余的環(huán)境調(diào)用等號賦值運(yùn)算符函數(shù)。13[例]

拷貝構(gòu)造函數(shù)的隱含作用classA{public:A(intn){m_n=n;} ~A(){}private:A(constA&r){m_n=r.m_n;}

int

m_n;};voidf(Aa){}Ag(intn){returnA(n);}voidmain(){Ad(2); Ab=10;Aa=d;f(b); }14

A類中拷貝構(gòu)造函數(shù)聲明為私有的,對象定義語句

[Aa=d;]等價(jià)于[Aa(d);],a(d)調(diào)用拷貝構(gòu)造函數(shù)??截悩?gòu)造函數(shù)是私有的,定義語句導(dǎo)致外部訪問私有的成員,因而彈出錯(cuò)誤提示。在函數(shù)對象數(shù)值形參入口f(Aa)和對象數(shù)值返回

returnA(n)時(shí)要求一個(gè)可訪問的拷貝構(gòu)造函數(shù)。函數(shù)f(Aa)是對象數(shù)值形參,調(diào)用f(b)引起拷貝構(gòu)造函數(shù)的調(diào)用,如果在虛實(shí)結(jié)合處不存在可訪問的拷貝構(gòu)造函數(shù),則導(dǎo)致錯(cuò)誤提示。15六、成員函數(shù)重載

類中的成員函數(shù)如全局函數(shù)一樣可以重載。析構(gòu)函數(shù)是唯一的,不能重載的函數(shù)是析構(gòu)函數(shù)。成員函數(shù)允許重載(overloading)其含義以兩個(gè)重載函數(shù)為例: typeCType::funct(t1v1,t2v2,tn

vn){語句序列;}typeCType::funct(type3v1,type4v2,typem

vn){語句序列;}16重載的成員函數(shù)是全限定名CType::funct相同形參列表類型、個(gè)數(shù)、位置有所不同的成員函數(shù)。成員函數(shù)重載在函數(shù)的調(diào)用點(diǎn)根據(jù)實(shí)參的類型和位置差異在編譯階段確定。

CType::用于函數(shù)名的名稱界定,因此另一個(gè)類中同名的成員函數(shù)funct是絕然不同的函數(shù),正是類域分辨符減少了同名函數(shù)的混亂,這就是封裝的優(yōu)點(diǎn)。17[例]

CRect類中的重載函數(shù)SetRect#include<string.h>#include<stdio.h>classCRect{public:longleft;longtop;longright;longbottom;

CRect(intl=1,intt=2,intr=3,intb=4);voidSetRect(intx1,inty1,intx2,inty2);voidSetRect(constCRect&r);voidShow(); };18voidCRect::Show(){printf("left=%d,top=%d,right=%d,bottom=%d;",

left,top,right,bottom);}voidCRect::SetRect(constCRect&r){left=r.left;top=r.top; right=r.right; bottom=r.bottom;}CRect::CRect(intl,intt,intr,intb){SetRect(l,t,r,b);}19voidCRect::SetRect(intl,intt,intright,intbottom){left=l;top=t;this->right=right;this->bottom=bottom;}voidmain(){ CRect

r,s;

r.Show();r.SetRect(5,6,7,8);

s.SetRect(r);s.Show();}//輸出:

left=1,top=2,right=3,bottom=4;left=5,top=6,right=7,bottom=820七、缺省參量的成員函數(shù)缺省參量的函數(shù)是形參列表參量具有事先預(yù)定的值,這給編程帶來的好處是:

首先提醒程序員合適的實(shí)參值大抵在什么范圍;

其次缺省參量對于函數(shù)的使用提供了方便,只需將缺省值作為實(shí)參帶入函數(shù)就能得到一致的結(jié)果。對于帶有缺省值的如下函數(shù)原型:

longCType::Set(intn,longm=10,shorts=5);

CType::CType(intn,longm=10,shorts=5);

在不引起重載調(diào)用歧義的情況下存在如下等價(jià)的調(diào)用格式:this->Set(7);this->Set(7,10);this->Set(7,10,5);

CTypea(7);CTypea(7,10);CTypea(7,10,5);21[例]

缺省參量的構(gòu)造函數(shù)和成員函數(shù)

#include<stdio.h>classCType{longm;intn;shorts;public:voidSet(intn,longm=10,shorts=5);

CType(intn=1,longm=10,shorts=5);voidShow();CType(){}};voidCType::Set(intn,longm,shorts){this->n=n;this->m=m;this->s=s;}

CType::CType(intn,longm,shorts){Set(n,m,s);}voidCType::Show() {printf("%d,%d,%d\n",n,m,s); }22

voidmain(){ CType*pthis=newCType(1);

pthis->Set(7,10,5); pthis->Show();

pthis->Set(7,10); pthis->Show();

CTypea(7,10,5);a.Show();

CTypec(7,10);c.Show(); }

為避免重載的歧義性,無參構(gòu)造函數(shù)和全部設(shè)置缺省值的構(gòu)造函數(shù)只提交一個(gè)版本。雖然兩者都提供并不算錯(cuò),但編譯器提出警告。對象定義{CTypeb;}既可以調(diào)用無參構(gòu)造函數(shù)也可以調(diào)用全部設(shè)置缺省值的構(gòu)造函數(shù);兩者都是缺省構(gòu)造函數(shù)。23八、編譯器默默提供的成員函數(shù)

對一個(gè)簡單的類聲明

[classCType{long

m_tData;};],編譯器暗中提交無參構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝構(gòu)造函數(shù)、賦值運(yùn)算符函數(shù)以及一對取地址運(yùn)算符函數(shù)。 取地址運(yùn)算函數(shù)存在一個(gè)只讀成員函數(shù),該函數(shù)用const關(guān)鍵此后置限定,用于取只讀對象的地址。 這些成員函數(shù)是公共訪問性質(zhì)的,僅在程序調(diào)用時(shí)才隱含生成不露聲色。24編譯器默默奉獻(xiàn)的成員函數(shù)清單如下:#include<stdio.h>#include<string.h>classCType{longm_tData;public:CType(){} ~CType(){}

CType(constCType&r);

CType&operator=(constCType&r);inlineCType*operator&();inlineconstCType*operator&()const;};25

intand=0;

CType::CType(const

CType&r){memcpy(this,&r,sizeof(CType

溫馨提示

  • 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

提交評論