久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

c 類的多態(tài)與虛函數(shù)的使用

 funson 2007-04-03
c++類的多態(tài)與虛函數(shù)的使用
2006-11-14 10:21:34  作者:ltsc  來源:  瀏覽次數(shù):26  網(wǎng)友評(píng)論0  文字大?。骸?a href="javascript:fontZoom(16)">大】【】【】 評(píng)分等級(jí):0

類的多態(tài)特性是支持面向?qū)ο蟮恼Z言最主要的特性,,有過非面向?qū)ο笳Z言開發(fā)經(jīng)歷的人,通常對(duì)這一章節(jié)的內(nèi)容會(huì)覺得不習(xí)慣,,因?yàn)楹芏嗳隋e(cuò)誤的認(rèn)為,,支持類的封裝的語言就是支持面向?qū)ο蟮模鋵?shí)不然,,Visual BASIC 6.0 是典型的非面向?qū)ο蟮拈_發(fā)語言,,但是它的確是支持類,支持類并不能說明就是支持面向?qū)ο?,能夠解決多態(tài)問題的語言,,才是真正支持面向?qū)ο蟮拈_發(fā)的語言,所以務(wù)必提醒有過其它非面向?qū)ο笳Z言基礎(chǔ)的讀者注意,!

   多態(tài)的這個(gè)概念稍微有點(diǎn)模糊,,如果想在一開始就想用清晰用語言描述它,讓讀者能夠明白,,似乎不太現(xiàn)實(shí),,所以我們先看如下代碼:



//程序作者:管寧
//站點(diǎn):www.
//所有稿件均有版權(quán),如要轉(zhuǎn)載,請(qǐng)務(wù)必著名出處和作者

//例程1
#include <iostream>
using namespace std;

class Vehicle
{
public:
Vehicle(float speed,int total)
{
Vehicle::speed=speed;
Vehicle::total=total;
}
void ShowMember()
{
cout<<speed<<"|"<<total<<endl;
}
protected:
float speed;
int total;
};
class Car:public Vehicle
{
public:
Car(int aird,float speed,int total):Vehicle(speed,total)
{
Car::aird=aird;
}
void ShowMember()
{
cout<<speed<<"|"<<total<<"|"<<aird<<endl;
}
protected:
int aird;
};

void main()
{
Vehicle a(120,4);
a.ShowMember();
Car b(180,110,4);
b.ShowMember();
cin.get();
}



  在c++種是允許派生類重載基類成員函數(shù)的,對(duì)于類的重載來說,,明確的,,不同類的對(duì)象,調(diào)用其類的成員函數(shù)的時(shí)候,,系統(tǒng)是知道如何找到其類的同名成員,,上面代碼中的a.ShowMember();,即調(diào)用的是Vehicle::ShowMember(),,b.ShowMember();,,即調(diào)用的是 Car::ShowMemeber();。

  但是在實(shí)際工作中,,很可能會(huì)碰到對(duì)象所屬類不清的情況,,下面我們來看一下派生類成員作為函數(shù)參數(shù)傳遞的例子,代碼如下:


//程序作者:管寧
//站點(diǎn):www.
//所有稿件均有版權(quán),如要轉(zhuǎn)載,請(qǐng)務(wù)必著名出處和作者


//例程2
#include <iostream>
using namespace std;

class Vehicle
{
public:
Vehicle(float speed,int total)
{
Vehicle::speed=speed;
Vehicle::total=total;
}
void ShowMember()
{
cout<<speed<<"|"<<total<<endl;
}
protected:
float speed;
int total;
};
class Car:public Vehicle
{
public:
Car(int aird,float speed,int total):Vehicle(speed,total)
{
Car::aird=aird;
}
void ShowMember()
{
cout<<speed<<"|"<<total<<"|"<<aird<<endl;
}
protected:
int aird;
};

void test(Vehicle &temp)
{
temp.ShowMember();
}

void main()
{
Vehicle a(120,4);
Car b(180,110,4);
test(a);
test(b);
cin.get();
}



  例子中,對(duì)象a與b分辨是基類和派生類的對(duì)象,,而函數(shù)test的形參卻只是Vehicle類的引用,,按照類繼承的特點(diǎn),系統(tǒng)把Car類對(duì)象看做是一個(gè) Vehicle類對(duì)象,,因?yàn)镃ar類的覆蓋范圍包含Vehicle類,,所以test函數(shù)的定義并沒有錯(cuò)誤,我們想利用test函數(shù)達(dá)到的目的是,,傳遞不同類對(duì)象的引用,,分別調(diào)用不同類的,重載了的,ShowMember成員函數(shù),但是程序的運(yùn)行結(jié)果卻出乎人們的意料,,系統(tǒng)分不清楚傳遞過來的基類對(duì)象還是派生類對(duì)象,,無論是基類對(duì)象還是派生類對(duì)象調(diào)用的都是基類的ShowMember成員函數(shù)。
為了要解決上述不能正確分辨對(duì)象類型的問題,,c++提供了一種叫做多態(tài)性(polymorphism)的技術(shù)來解決問題,,對(duì)于例程序1,這種能夠在編譯時(shí)就能夠確定哪個(gè)重載的成員函數(shù)被調(diào)用的情況被稱做先期聯(lián)編(early binding),,而在系統(tǒng)能夠在運(yùn)行時(shí),,能夠根據(jù)其類型確定調(diào)用哪個(gè)重載的成員函數(shù)的能力,稱為多態(tài)性,,或叫滯后聯(lián)編(late binding),,下面我們要看的例程3,就是滯后聯(lián)編,,滯后聯(lián)編正是解決多態(tài)問題的方法,。


代碼如下:


//程序作者:管寧
//站點(diǎn):www.
//所有稿件均有版權(quán),如要轉(zhuǎn)載,請(qǐng)務(wù)必著名出處和作者

//例程3
#include <iostream>
using namespace std;

class Vehicle
{
public:
Vehicle(float speed,int total)
{
Vehicle::speed = speed;
Vehicle::total = total;
}
virtual void ShowMember()//虛函數(shù)
{
cout<<speed<<"|"<<total<<endl;
}
protected:
float speed;
int total;
};
class Car:public Vehicle
{
public:
Car(int aird,float speed,int total):Vehicle(speed,total)
{
Car::aird = aird;
}
virtual void ShowMember()//虛函數(shù),在派生類中,由于繼承的關(guān)系,,這里的virtual也可以不加
{
cout<<speed<<"|"<<total<<"|"<<aird<<endl;
}
public:
int aird;
};

void test(Vehicle &temp)
{
temp.ShowMember();
}

int main()
{
Vehicle a(120,4);
Car b(180,110,4);
test(a);
test(b);
cin.get();
}



  多態(tài)特性的工作依賴虛函數(shù)的定義,,在需要解決多態(tài)問題的重載成員函數(shù)前,加上virtual關(guān)鍵字,,那么該成員函數(shù)就變成了虛函數(shù),,從上例代碼運(yùn)行的結(jié)果看,系統(tǒng)成功的分辨出了對(duì)象的真實(shí)類型,,成功的調(diào)用了各自的重載成員函數(shù),。


   多態(tài)特性讓程序員省去了細(xì)節(jié)的考慮,提高了開發(fā)效率,,使代碼大大的簡(jiǎn)化,,當(dāng)然虛函數(shù)的定義也是有缺陷的,因?yàn)槎鄳B(tài)特性增加了一些數(shù)據(jù)存儲(chǔ)和執(zhí)行指令的開銷,,所以能不用多態(tài)最好不用,。


  虛函數(shù)的定義要遵循以下重要規(guī)則:

1.如果虛函數(shù)在基類與派生類中出現(xiàn),,僅僅是名字相同,而形式參數(shù)不同,,或者是返回類型不同,,那么即使加上了virtual關(guān)鍵字,也是不會(huì)進(jìn)行滯后聯(lián)編的,。

2.只有類的成員函數(shù)才能說明為虛函數(shù),,因?yàn)樘摵瘮?shù)僅適合用與有繼承關(guān)系的類對(duì)象,所以普通函數(shù)不能說明為虛函數(shù),。

3.靜態(tài)成員函數(shù)不能是虛函數(shù),因?yàn)殪o態(tài)成員函數(shù)的特點(diǎn)是不受限制于某個(gè)對(duì)象,。

4.內(nèi)聯(lián)(inline)函數(shù)不能是虛函數(shù),,因?yàn)閮?nèi)聯(lián)函數(shù)不能在運(yùn)行中動(dòng)態(tài)確定位置,。即使虛函數(shù)在類的內(nèi)部定義定義,但是在編譯的時(shí)候系統(tǒng)仍然將它看做是非內(nèi)聯(lián)的,。

5.構(gòu)造函數(shù)不能是虛函數(shù),,因?yàn)闃?gòu)造的時(shí)候,對(duì)象還是一片位定型的空間,,只有構(gòu)造完成后,,對(duì)象才是具體類的實(shí)例。

6.析構(gòu)函數(shù)可以是虛函數(shù),而且通常聲名為虛函數(shù),。

   說明一下,,雖然我們說使用虛函數(shù)會(huì)降低效率,但是在處理器速度越來越快的今天,,將一個(gè)類中的所有成員函數(shù)都定義成為virtual總是有好處的,,它除了會(huì)增加一些額外的開銷是沒有其它壞處的,對(duì)于保證類的封裝特性是有好處的,。

對(duì)于上面虛函數(shù)使用的重要規(guī)則6,,我們有必要用實(shí)例說明一下,為什么具備多態(tài)特性的類的析構(gòu)函數(shù),,有必要聲明為virtual,。

代碼如下


//程序作者:管寧
//站點(diǎn):www.
//所有稿件均有版權(quán),如要轉(zhuǎn)載,請(qǐng)務(wù)必著名出處和作者

#include <iostream>
using namespace std;

class Vehicle
{
public:
Vehicle(float speed,int total)
{
Vehicle::speed=speed;
Vehicle::total=total;
}
virtual void ShowMember()
{
cout<<speed<<"|"<<total<<endl;
}
virtual ~Vehicle()
{
cout<<"載入Vehicle基類析構(gòu)函數(shù)"<<endl;
cin.get();
}
protected:
float speed;
int total;
};
class Car:public Vehicle
{
public:
Car(int aird,float speed,int total):Vehicle(speed,total)
{
Car::aird=aird;
}
virtual void ShowMember()
{
cout<<speed<<"|"<<total<<"|"<<aird<<endl;
}
virtual ~Car()
{
cout<<"載入Car派生類析構(gòu)函數(shù)"<<endl;
cin.get();
}
protected:
int aird;
};

void test(Vehicle &temp)
{
temp.ShowMember();
}
void DelPN(Vehicle *temp)
{
delete temp;
}
void main()
{
Car *a=new Car(100,1,1);
a->ShowMember();
DelPN(a);
cin.get();
}


  從上例代碼的運(yùn)行結(jié)果來看,當(dāng)調(diào)用DelPN(a);后,,在析構(gòu)的時(shí)候,,系統(tǒng)成功的確定了先調(diào)用Car類的析構(gòu)函數(shù),而如果將析構(gòu)函數(shù)的virtual修飾去掉,,再觀察結(jié)果,,會(huì)發(fā)現(xiàn)析構(gòu)的時(shí)候,始終只調(diào)用了基類的析構(gòu)函數(shù),,由此我們發(fā)現(xiàn),,多態(tài)的特性的virtual修飾,,不單單對(duì)基類和派生類的普通成員函數(shù)有必要,而且對(duì)于基類和派生類的析構(gòu)函數(shù)同樣重要,。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多