溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

C++虛函數(shù)怎么使用

發(fā)布時(shí)間:2022-08-25 10:01:50 來(lái)源:億速云 閱讀:140 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本篇內(nèi)容介紹了“C++虛函數(shù)怎么使用”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

一、虛函數(shù)

首先來(lái)看下面這一段代碼,首先創(chuàng)建兩個(gè)類(lèi),一個(gè)是Dog,另一個(gè)是Cat,他們有一個(gè)共同的屬性:Run。在定義中每個(gè)動(dòng)物都需要?jiǎng)?chuàng)建一個(gè)類(lèi),比較繁瑣,所以在下面的例子中,我們可以把他們簡(jiǎn)化。

#include <iostream>
using namespace std;
class Dog{
public:
    void Run(){
        cout<<"Dog->Run"<<endl;
    }    
};
class Cat{
public:
    void Run(){
        cout<<"Cat->Run"<<endl;
    }
};
int main()
{
    Dog d;
    d.Run();
    Cat c;
    c.Run();
    return 0;
}

C++虛函數(shù)怎么使用

這里使用多態(tài)和虛函數(shù),而Animal提供統(tǒng)一的接口,供子類(lèi)使用,雖然代碼繁瑣,但提高了整個(gè)工程的可擴(kuò)展性和靈活性。

在普通函數(shù)前加上關(guān)鍵字 virtual 構(gòu)成虛函數(shù),子類(lèi)需要重寫(xiě)父類(lèi)的虛函數(shù),這樣在調(diào)用的時(shí)候,會(huì)覆蓋掉父類(lèi)的虛函數(shù) Run,去執(zhí)行子類(lèi)的Run。

#include <iostream>
using namespace std;
class Animal{
public:
    virtual void Run(){
        cout<<"Animal->Run"<<endl;
    }
};
class Dog :public Animal{
public:
    void Run(){
        cout<<"Dog->Run"<<endl;
    }    
};
class Cat:public Animal{
public:
    void Run(){
        cout<<"Cat->Run"<<endl;
    }
};
int main()
{
    Animal *ani;
    ani = new Dog;
    ani->Run();
    delete ani;
    ani = new Cat;
    ani->Run();
    delete ani;
    return 0;
}

結(jié)果如下:

C++虛函數(shù)怎么使用

所以在這里只需要修改ani的指向就可以實(shí)現(xiàn)不同方法。如果不存在虛函數(shù),把Animal類(lèi)的關(guān)鍵詞virtual去掉會(huì)怎么樣呢,顯然,他們會(huì)默認(rèn)實(shí)現(xiàn)父類(lèi)Run的方法。

class Animal{
public:
    void Run(){
        cout<<"Animal->Run"<<endl;
    }
};

C++虛函數(shù)怎么使用

所以引入虛函數(shù)是為了實(shí)現(xiàn)動(dòng)態(tài)多態(tài),指向不同的子類(lèi)來(lái)實(shí)現(xiàn)不同的方法。

二、虛函數(shù)與純虛函數(shù)的區(qū)別

因?yàn)楦割?lèi)的函數(shù)可以不做任何操作,所以這里可以直接等于0;實(shí)現(xiàn)純虛函數(shù)。

//虛函數(shù)
class Animal{
public:
    virtual void Run(){
        cout<<"Animal->Run"<<endl;
    }
};
//純虛函數(shù)
class Animal{
public:
    virtual void Run()=0;
};

虛函數(shù)與純虛函數(shù)的區(qū)別:

純虛函數(shù)只是一個(gè)接口,只能供子類(lèi)去重寫(xiě)實(shí)現(xiàn)方法。而虛函數(shù)在里面也可以去實(shí)現(xiàn)父類(lèi)的功能。只需要指向父類(lèi)的方法即可。

總結(jié):虛函數(shù)在子類(lèi)里面也可以不進(jìn)行重寫(xiě),但純虛函數(shù)必須在子類(lèi)去實(shí)現(xiàn),如果把子類(lèi)中的Run方法去掉,只留下父類(lèi)中的純虛函數(shù),那么編譯器會(huì)報(bào)錯(cuò),這里大家可以試試。

三、動(dòng)態(tài)多態(tài)

Animal內(nèi)部的結(jié)構(gòu)是什么樣呢?這里有一個(gè)虛函數(shù)指針(vfptr)和虛函數(shù)表(vftable)。 指針(vfptr)指向虛函數(shù)表,在虛函數(shù)表(vftable)內(nèi)記錄著虛函數(shù)的地址,即Run函數(shù)的地址。

C++虛函數(shù)怎么使用

當(dāng)子類(lèi)的Dog去繼承父類(lèi)后,父類(lèi)的虛函數(shù)表相應(yīng)的也繼承下來(lái),子類(lèi)也會(huì)保存一份和父類(lèi)相同的。

注意!這時(shí)候如果發(fā)生重寫(xiě),即子類(lèi)重寫(xiě)了父類(lèi)的虛函數(shù),則子類(lèi)的虛函數(shù)表會(huì)覆蓋父類(lèi)繼承下來(lái)的虛函數(shù)表。但父類(lèi)的虛函數(shù)表不會(huì)發(fā)生改變。

C++虛函數(shù)怎么使用

當(dāng)父類(lèi)的指針或者引用指向子類(lèi)的對(duì)象時(shí),就發(fā)生了多態(tài)。

下面的代碼中是指向了Dog,所以會(huì)去Dog的虛函數(shù)表中找到相應(yīng)的函數(shù),在運(yùn)行階段發(fā)生了動(dòng)態(tài)多態(tài)。

    Animal *ani;
    ani = new Dog;
    ani->Run();

“C++虛函數(shù)怎么使用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

c++
AI