在類的定義中,前面有virtual關鍵字的成員函式就是虛函式。
virtual關鍵字只用在類定義裡的函式宣告中,寫函式體時不用。
建構函式和靜態成員函式不能是虛函式。
派生類的指標可以賦給基類指標。
通過基類指標呼叫基類和派生類中的同名虛函式時:
(1)若該指標指向乙個基類的物件,那麼被呼叫的是基類的虛函式。
(2)若該指標指向乙個派生類的物件,那麼被呼叫的是派生類的虛函式。
這種機制叫做"多型"。
class cbase
};class cderived :public cbase
};int main()
派生類的物件可以賦給基類引用
通過基類引用呼叫基類和派生類中的同名虛函式時:
(1)若該引用引用的是乙個基類的物件,那麼被呼叫的基類的虛函式。
(2)若該引用引用的是乙個派生類的物件,那麼被呼叫的是派生類的虛函式。
這種機制也叫做「多型」。
class cbase
};class cderived :public cbase
};int main()
class base
virtual void fun2()
}; class derived :public base
};int main()
在非建構函式和非析構函式中呼叫虛函式,所呼叫的虛函式是哪乙個取決於其指向的物件型別或者其引用的物件型別。
注意:在析構函式和建構函式中呼叫虛函式不是多型。編譯時即可確定,呼叫的函式是自己的類或基類中定義的函式,不會等到執行時才決定呼叫自己的還是派生類的函式。
另外,多型要保證派生函式的形式引數要和基類的相同,派生類的函式可以virtual不進行宣告,但是基類的函式如果是用來實現多型的話一定要用virtual宣告。
動態的關鍵在於通過基類指標或引用呼叫乙個虛函式時,編譯時不確定到底呼叫的是基類還是派生類的函式,執行時來確定----這叫「動態聯編」。
每乙個有虛函式的類(或有虛函式的類的派生類)都有乙個虛函式表,該類的任何物件中都放在虛函式表的指標。虛函式表中列出了該類的虛函式位址。
每乙個有虛函式的類都會多出來4個位元組(具體取決於機器字長),這些多出來的位元組就是來放虛函式表的位址的(通常放在類的儲存空間的頭部)。
多型的函式呼叫語句被編譯成一系列根據基類指標所指向的(或基類引用所引用的)物件中存放的虛函式表的位址,在虛函式表中查詢虛函式位址,並呼叫虛函式的指令。
多型的實現需要額外付出一些時間和空間上的開銷。
#includeusing namespace std;
class a
};class b:public a
};int main(void)
輸出結果為:
b::func
a::func
這裡第二個func的呼叫的是a中的func只是因為我們使用了指標改變了該物件的虛函式表位址。
通過基類的指標刪除派生類物件時,通常情況下只呼叫基類的析構函式,但是刪除乙個派生類的物件時,應該先呼叫派生類的析構函式,然後呼叫基類的析構函式。
解決方法是把基類的析構函式宣告為virtual:
派生類的析構函式可以virtual不進行宣告
通過基類的指標刪除派生類的析構函式,然後呼叫基類的析構函式。
一般來說,乙個類如果定義了虛函式,則應該將析構函式也定義成虛函式。或者,乙個類打算作為基類使用,也應該將析構函式定義成虛函式。
沒有函式體地虛函式,具體寫法為virtual void fun()=0
。
包含純虛函式的類叫抽象類。
抽象類還能作為基類來派生新類使用,不能建立抽象類的物件。
抽象類的指標和引用可以指向由抽象類派生出來的類的物件。(可以定義抽象類的指標和引用,但是不能建立類的實體)。
在抽象類的成員函式內可以呼叫純虛函式,但是在建構函式或者析構函式內部不能呼叫純虛函式(這是因為析構函式和建構函式不屬於多型,而呼叫自己為空的純虛函式是沒有意義的)。
如果乙個類從抽象派生而來,那麼當且僅當它實現類基類中的所有純虛函式,它才能成為非抽象類。
詳見部落格:多型,過載,覆蓋區別與聯絡
在物件導向的抽象設計中使用多型,能夠增強抽象的可擴充性,即程式需要修改或增加功能的時候,需要改動和增加的**較少。
MOOC C 筆記(五) 繼承
繼承 在定義乙個新的類b時,如果該類與某個個已有的類a相似 指的是b擁有a的全部特點 那麼就可以把a作為乙個基類,而把b作為基類的乙個派生類 也稱子類 派生類是通過對基類進行修改和擴充得到的。在派生類中,可以擴充新的成員變數和成員函式。派生類一經定義後,可以獨立使用,不依賴於基類。派生類擁有基類的全...
北京大學MOOC C 學習筆記(五)虛函式和多型
在類的定義中,前面有 virtual 關鍵字的成員函式就是虛函式。class base int base get virtual 關鍵字只用在類定義裡的函式宣告中,寫函式體時不用。若該指標指向乙個基類的物件,那麼被呼叫是基類的虛函式 若該指標指向乙個派生類的物件,那麼被呼叫的是派生類的虛函式。這種機...
中國大學MOOC C語言筆記03
5.1迴圈控制 判斷素數 如下 include int main printf f d f n n,sum return 0 求和 f n 1 1 2 1 3 1 4 1 5 如下 include int main printf f d f n n,sum return 0 求最大公約數 兩種演算法...