多態性之超載與虛函數

面向對象編程(Object Oriented Programming,OOP,面向對象程序設計)有三個重要特徵:封裝性、繼承性和多態性。

多態性

不同的對象接收到同樣的指令(調用同一函數)會產生不一樣的結果,謂之多態性

舉個簡單的例子,【動物類】派生出【貓類】和【狗類】。【貓類】對象和【狗類】對象調用同一函數【叫】時,前者產生“喵~~”,而後者產生“汪汪汪”。這就是多態性,讓程序生動而有魅力

函數重載與靜態聯編

多個函數使用同一函數名,但這些同名函數具有不同的原型(形參表不同),這就是函數重載

因爲重載函數的形參表是不同的,因此係統在編譯過程中就可以確定該函數與程序中的哪一段函數相聯繫,即在編譯時就已確定函數調用語句對應的函數體代碼,故稱爲靜態聯編


函數超載與動態聯編

多個函數,有完全相同的函數原型,卻可以不同的函數體,這種現象就叫函數超載

由於超載函數允許不同的函數具有相同的函數原型,因此在編譯階段系統無法判斷此次調用應執行哪一段函數代碼。只有在運行過程中執行到該函數調用時,才能臨時判斷應執行哪一段函數代碼,故稱爲動態聯編

爲了實現虛函數與動態聯編,我們需要用到一個概念,那就是虛函數


虛函數

在基類中將某一非靜態成員函數的屬性說明爲virtual,則稱該函數爲虛函數

格式

virtual <返回類型><函數名>(<參數表>){
    // 函數體
}

說明方法

基類中某函數被說明爲虛函數,其派生類中也列出與該函數原型相同但函數體可以不同的函數成員。

示例

class Animal{
    virtual void sound(){ sound.. }
};
class Cat{
    virtual void sound(){ Meow~~~ }
};
class Dog{
    virtual void sound(){ Bark!!! }
};
class Bird{
    virtual void sound(){ Tweet^^^ }
};

注意

1.如果不準備在基類的虛函數中做任何的事情,可用如下格式將該函數說明爲純虛函數。(詳見 純虛函數與抽象基類

virtual <函數原型>=0;

2.在派生類說明中關鍵字“virtual”可以缺省,它們自動定義爲虛函數,但在基類中不可缺省。

3.構造函數不能說明爲虛函數,但析構函數可以說明爲虛函數

使用方法

1.直接通過派生類對象調用它們各自實現的虛函數

Cat cat;        cat.sound();
Dog dog;        dog.sound();
Bird bird;      bird.sound();

2.使用指向基類的指針,然後再通過將派生類對象的地址賦給基類指針變量,從而通過指針間接調用派生類各自實現的虛函數。

Cat cat;
Dog dog;
Bird bird;
Animal *pa;
pa = &cat;      pa->sound();
pa = &dog;      pa->sound();
pa = &bird;     pa->sound();

虛函數的好處

1.使程序簡單易讀,減少限定符的使用。

2.使程序模塊間獨立性加強,隱藏函數細節,提高程序封裝性。

3.增加程序易維護性,新增派生類更容易。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章