虛函數的作用

來源:互聯網
上載者:User

虛函數的作用是允許在衍生類別中重新定義與基類同名的函數,並且可以通過基類指標或引用來訪問基類和衍生類別中的同名函數。

 

例:基類與衍生類別中有同名函數。

在下面的程式中Student是基類,Graduate是衍生類別,它們都有display這個同名的函數。

#include <iostream>

#include <string>

using namespace std;

//聲明基類Student

class Student

{public:

   Student(int, string,float);//聲明建構函式

   void display( );                                             //聲明輸出函數

  protected:                                      //受保護的成員,衍生類別可以訪問

   int num;

   string name;

   float score;

 };

//Student類成員函數的實現

Student::Student(int n, string nam,float s)                     //定義建構函式

 {num=n;name=nam;score=s;}

void Student::display( )                                        //定義輸出函數

{cout<<″num:″<<num<<″//nname:″<<name<<″//nscore:″<<score<<″//n//n″;}

 

//聲明公用衍生類別Graduate

class Graduate:public Student

{public:

   Graduate(int, string, float, float);                          //聲明建構函式

   void display( );                                             //聲明輸出函數

private:

  float pay;

};

// Graduate類成員函數的實現

void Graduate::display( )                                       //定義輸出函數

 {cout<<″num:″<<num<<″//nname:″<<name<<″//nscore:″<<score<<″//npay=″<<pay<<endl;}

Graduate::Graduate(int n, string nam,float s,float p):Student(n,nam,s),pay(p){ }

//主函數

int main()

 {Student stud1(1001,″Li″,87.5);                   //定義Student類對象stud1

  Graduate grad1(2001,″Wang″,98.5,563.5);          //定義Graduate類對象grad1

  Student *pt=&stud1;                            //定義指向基類對象的指標變數pt

  pt->display( );

  pt=&grad1;

  pt->display( );

  return 0;

 }

運行結果如下,請仔細分析。

num:1001(stud1的資料)

name:Li

score:87.5

num:2001                  (grad1中基類部分的資料)

name:wang

score:98.5

 

下面對程式作一點修改,在Student類中聲明display函數時,在最左面加一個關鍵字virtual,即

virtual void display( );

這樣就把Student類的display函式宣告為虛函數。程式其他部分都不改動。再編譯和運行程式,請注意分析運行結果:

num:1001(stud1的資料)

name:Li

score:87.5

 

num:2001                  (grad1中基類部分的資料)

name:wang

score:98.5

pay=1200                   (這一項以前是沒有的)

 

由虛函數實現的動態多態性就是: 同一類族中不同類的對象,對同一函數調用作出不同的響應。虛函數的使用方法是:

(1) 在基類用virtual聲明成員函數為虛函數。這樣就可以在衍生類別中重新定義此函數,為它賦予新的功能,並能方便地被調用。

在類外定義虛函數時,不必再加virtual。

(2) 在衍生類別中重新定義此函數,要求函數名、函數類型、函數參數個數和類型全部與基類的虛函數相同,並根據衍生類別的需要重新定義函數體。

C++規定,當一個成員函數被聲明為虛函數後,其衍生類別中的同名函數都自動成為虛函數。因此在衍生類別重新聲明該虛函數時,可以加virtual,也可以不加,但習慣上一般在每一層聲明該函數時都加virtual,使程式更加清晰。

如果在衍生類別中沒有對基類的虛函數重新定義,則衍生類別簡單地繼承其直接基類的虛函數。

(3) 定義一個指向基類對象的指標變數,並使它指向同一類族中需要調用該函數的對象。

(4) 通過該指標變數調用此虛函數,此時調用的就是指標變數指向的對象的同名函數。

通過虛函數與指向基類對象的指標變數的配合使用,就能方便地調用同一類族中不同類的同名函數,只要先用基類指標指向即可。如果指標不斷地指向同一類族中不同類的對象,就能不斷地調用這些對象中的同名函數。這就如同前面說的,不斷地告訴出租車司機要去的目的地,然後司機把你送到你要去的地方。

需要說明;有時在基類中定義的非虛函數會在衍生類別中被重新定義,如果用基類指標調用該成員函數,則系統會調用對象中基類部分的成員函數;如果用衍生類別指標調用該成員函數,則系統會調用衍生類別對象中的成員函數,這並不是多態性行為(使用的是不同類型的指標),沒有用到虛函數的功能。

以前介紹的函數重載處理的是同一層次上的同名函數問題,而虛函數處理的是不同派生層次上的同名函數問題,前者是橫向重載,後者可以理解為縱向重載。但與重載不同的是: 同一類族的虛函數的首部是相同的,而函數重載時函數的首部是不同的(參數個數或類型不同)。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.