C++ 的 virtual function

在資結的作業裡,TA會先給出一套已經定義好的標頭檔(header file),並讓你繼承與實作內部函式(function)。而在他的標頭檔案裡,總是會在要重載的函式前加上 virtual 這個關鍵字,讓人實在無法忽略,於是特別寫了這篇來紀錄 virtual 這個字的實際效果與使用方式。




在書上, virtual 的含義:(引自C++程式設計原理與實務, ISBN978-986-2571-85-9, A-46)
為幫助理解在下便獻醜添加了些詞句,。

虛擬函數其定義了與衍生類別同名(如同B :public A, 則B為A的衍生類別) 、使用同引數形態(可以簡單想像成A, B裡各有一個長得一模一樣的函式),在呼叫該函式時提供一個呼叫界面。讓我們在呼叫虛擬函式時,大部份被真正呼叫到為衍生類別中定義的函式,而非基礎類別的函式。


利用一個範例來理解他,故事情節如下:
在學校裡學習的人統稱做 <Student>, 有三個學生<Fred>, <Jack>, 還有一個不告訴你名字的<Student>, 今天老師沒辦法分辨出他們之間的差別,只知道三個人分別叫做A, B, C。不得以下只好問他們一個問題。由於他們的身份不同,說出的話一定要不一樣,藉此來分辨他們的身份。
在這個情境下,我定義了三區塊的程式碼,分別是<class>宣告、 <class>實作、<main>實作。
另外,這裡有用到一個蠻特別的寫法
Student *A = new Fred
一個父類別的指標允許指到一個子類別(這也是 virtual function 的優勢之一) 


// class define in VirtualFunction.h
class Student //Student身份
{
public:
    virtual void SaySomething();
};

class Fred :public Student //Fred 同時也俱有Student身份
{
public:
    void Saysomething();
};

class Jack :public Student //Jack 同時也俱有Student身份
{
public:
    void Saysomething();
};

//下面這個function是老師向他們提出的問題
void Call(Student & person)
{
    person.Saysomething();
}

#include "VirtualFunction.h"
// class function implement
void Student::Saysomething()
{
    std::cout<<"I am a Student!\n";
}

void Fred::Saysomething()
{
    std::cout<<"I am Fred!\n";
}

void Jack::Saysomething()
{
    std::cout<<"I am Jack!\n";
}


#include <iostream>
#include "VirtualFunction.h"
// main function
int main(int argc, char *argv[])
{
    Student *A = new Student;
    Student *B = new Fred;
    Student *C = new Jack;
    Call(*A);
    Call(*B);
    Call(*C);
    return 0;
}

以下為執行結果
➜  class  clang++ main.cpp
➜  class  ./a.out
I am a Student!
I am Fred!
I am Jack!

藉由上面的結果,我們可以很明顯看到在那個Call function裡面,我只宣告它是一個<Student>的身份,但是在呼叫 SaySomething 時,他就會去呼叫到子類別裡的函式,而非母函式。因此多形的好處得以體現,我們成功地把<Student>抽象化了,以後不管我們有多少個繼承<Student>的類別,Call function都可以正確的抓到我們想要的函式。


這只是 virtual 的第一種寫法,在母類別裡我們依舊有實作屬於母類別的函式,有沒有辦法強迫所有的子類別都必須要實作自己的函式呢?
當然有!
那就是在函式宣告的最後方加上 "= 0" 就可以了!

這次的 virtual 就記錄到這邊了。
2013-4-24 22:18

1 意見:

匿名 2022年4月8日 凌晨3:31  

Casino Bonus Codes - December 2021
No deposit bonus casino promotions. We recommend 2021 kadangpintar casino bonus wooricasinos.info codes and promos for new players. We also list new poormansguidetocasinogambling casino 1xbet korean bonuses for December 2021. worrione

張貼留言

湖水偶然間遇上詩人的一片雲,而你因為機緣踏入這裡
何不留下一絲的吉光片羽呢?

關於我自己

在資訊工程走著的孩子,有太多的事情不懂,太多的東西想瞭解,一頭栽入無遠弗屆的世界!

搜尋此網誌

總網頁瀏覽量

技術提供:Blogger.