国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

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

2019-11-17 05:05:07
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
   類的多態(tài)特性是支持面向?qū)ο蟮恼Z(yǔ)言最主要的特性,有過(guò)非面向?qū)ο笳Z(yǔ)言開(kāi)發(fā)經(jīng)歷的人,通常對(duì)這一章節(jié)的內(nèi)容會(huì)覺(jué)得不習(xí)慣,因?yàn)楹芏嗳隋e(cuò)誤的認(rèn)為,支持類的封裝的語(yǔ)言就是支持面向?qū)ο蟮模鋵?shí)不然,
Visual BASIC 6.0 是典型的非面向?qū)ο蟮拈_(kāi)發(fā)語(yǔ)言,但是它的確是支持類,支持類并不能說(shuō)明就是支持面向?qū)ο螅軌蚪鉀Q多態(tài)問(wèn)題的語(yǔ)言,才是真正支持面向?qū)ο蟮拈_(kāi)發(fā)的語(yǔ)言,所以務(wù)必提醒有過(guò)其它非面向?qū)ο笳Z(yǔ)言基礎(chǔ)的讀者注重!

  多態(tài)的這個(gè)概念稍微有點(diǎn)模糊,假如想在一開(kāi)始就想用清楚用語(yǔ)言描述它,讓讀者能夠明白,似乎不太現(xiàn)實(shí),所以我們先看如下代碼://例程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++中是答應(yīng)派生類重載基類成員函數(shù)的,對(duì)于類的重載來(lái)說(shuō),明確的,不同類的對(duì)象,調(diào)用其類的成員函數(shù)的時(shí)候,系統(tǒng)是知道如何找到其類的同名成員,上面代碼中的a.ShowMember();,即調(diào)用的是Vehicle::ShowMember(),b.ShowMember();,即調(diào)用的是Car::ShowMemeber();。 更多文章 更多內(nèi)容請(qǐng)看C/C++技術(shù)專題專題,或   但是在實(shí)際工作中,很可能會(huì)碰到對(duì)象所屬類不清的情況,下面我們來(lái)看一下派生類成員作為函數(shù)參數(shù)傳遞的例子,代碼如下:
//例程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類的引用,按照類繼續(xù)的特點(diǎn),系統(tǒng)把Car類對(duì)象看做是一個(gè)Vehicle類對(duì)象,因?yàn)镃ar類的覆蓋范圍包含Vehicle類,所以test函數(shù)的定義并沒(méi)有錯(cuò)誤,我們想利用test函數(shù)達(dá)到的目的是,傳遞不同類對(duì)象的引用,分別調(diào)用不同類的,重載了的,ShowMember成員函數(shù),但是程序的運(yùn)行結(jié)果卻出乎人們的意料,系統(tǒng)分不清楚傳遞過(guò)來(lái)的基類對(duì)象還是派生類對(duì)象,無(wú)論是基類對(duì)象還是派生類對(duì)象調(diào)用的都是基類的ShowMember成員函數(shù)。 更多文章 更多內(nèi)容請(qǐng)看C/C++技術(shù)專題專題,或   為了要解決上述不能正確分辨對(duì)象類型的問(wèn)題,c++提供了一種叫做多態(tài)性(polymorphism)的技術(shù)來(lái)解決問(wèn)題,對(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)問(wèn)題的方法。


  代碼如下://例程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ù),在派生類中,由于繼續(xù)的關(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)問(wèn)題的重載成員函數(shù)前,加上virtual要害字,那么該成員函數(shù)就變成了虛函數(shù),從上例代碼運(yùn)行的結(jié)果看,系統(tǒng)成功的分辨出了對(duì)象的真實(shí)類型,成功的調(diào)用了各自的重載成員函數(shù)。   多態(tài)特性讓程序員省去了細(xì)節(jié)的考慮,提高了開(kāi)發(fā)效率,使代碼大大的簡(jiǎn)化,當(dāng)然虛函數(shù)的定義也是有缺陷的,因?yàn)槎鄳B(tài)特性增加了一些數(shù)據(jù)存儲(chǔ)和執(zhí)行指令的開(kāi)銷,所以能不用多態(tài)最好不用。 更多文章 更多內(nèi)容請(qǐng)看C/C++技術(shù)專題專題,或   虛函數(shù)的定義要遵循以下重要規(guī)則:

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

  2.只有類的成員函數(shù)才能說(shuō)明為虛函數(shù),因?yàn)樘摵瘮?shù)僅適合用與有繼續(xù)關(guān)系的類對(duì)象,所以普通函數(shù)不能說(shuō)明為虛函數(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ù)。

  說(shuō)明一下,雖然我們說(shuō)使用虛函數(shù)會(huì)降低效率,但是在處理器速度越來(lái)越快的今天,將一個(gè)類中的所有成員函數(shù)都定義成為virtual總是有好處的,它除了會(huì)增加一些額外的開(kāi)銷是沒(méi)有其它壞處的,對(duì)于保證類的封裝特性是有好處的。  對(duì)于上面虛函數(shù)使用的重要規(guī)則6,我們有必要用實(shí)例說(shuō)明一下,為什么具備多態(tài)特性的類的析構(gòu)函數(shù),有必要聲明為virtual。

  代碼如下:#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é)果來(lái)看,當(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ù)同樣重要。 更多文章 更多內(nèi)容請(qǐng)看C/C++技術(shù)專題專題,或

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 新丰县| 龙陵县| 潜江市| 荔波县| 盐山县| 舒城县| 郑州市| 腾冲县| 甘洛县| 嘉禾县| 汾西县| 汶川县| 漠河县| 枣阳市| 资兴市| 明光市| 腾冲县| 正阳县| 阳信县| 长葛市| 株洲县| 黄浦区| 长宁区| 甘孜县| 无极县| 桃江县| 桂阳县| 栾川县| 蓝山县| 岳阳县| 抚州市| 佛冈县| 弥渡县| 永善县| 阳春市| 和硕县| 新建县| 崇州市| 玛曲县| 苏尼特左旗| 阜城县|