當某個虛函式通過指標或者引用呼叫時,編譯器產生的**直到執行時才能確定應該呼叫哪個版本的函式,被呼叫的函式是與繫結到指標或引用上的物件的動態型別相匹配的那個。
必須注意的是,動態繫結只有當我們通過指標或引用呼叫虛函式時才會發生。如果通過普通的型別(非引用非指標)的表示式呼叫虛函式時,編譯器就會將呼叫的版本確定下來。
一旦某個函式被宣告成虛函式,則在所有的派生類中它都是虛函式,在派生類中覆蓋乙個虛函式時,可以再次使用virtual
關鍵字指出該函式的性質,也可以不指明。
乙個派生類的函式如果覆蓋了某個繼承而來的虛函式,則它的形參型別必須與它覆蓋的基類函式完全一致。派生類中虛函式的返回型別也應該與基類函式匹配,該規則存在乙個例外:類的虛函式返回型別是本身的指標或引用。
c++ 11 新標準中可以使用override
關鍵字來說明派生類中的虛函式,如果使用override
標記某個函式,該函式沒有覆蓋已存在的虛函式,此時編譯器將報錯。
還可以將某個函式指定為final
,如果函式被定義成final
了,則之後任何嘗試覆蓋該函式的操作都將引發錯誤。
final
和override
關鍵字應該出現在形參列表(包括任何const
或引用修飾符)以及尾置返回型別之後。
虛函式可以有預設實參,如果某次虛函式呼叫使用了預設實參,則該實參值由本次呼叫的靜態型別決定:如果通過基類的指標或引用呼叫函式,則使用基類中定義的預設實參,即使實際執行的是派生類的函式版本。
如果虛函式使用預設實參,則基類和派生類中定義的預設實參最好一致。
有些時候希望對虛函式的呼叫不要進行動態繫結,而是強迫其執行虛函式的某個特定版本,使用作用域符可以實現這一目的:
double undiscounted = base->quote::net_price(24);
該**呼叫quote
的net_price
函式,不管base
指向的物件型別到底是什麼。
當乙個派生類虛函式呼叫它覆蓋的基類的虛函式版本時,一般採用迴避機制。此時如果不使用作用域符,則在執行時該呼叫將被解析成對派生類的呼叫,從而導致無限遞迴。
純虛函式無需定義,通過在函式體的位置書寫=0
就可以將乙個虛函式說明為純虛函式。其中=0
只能出現在類內部的虛函式宣告語句中。
可以為乙個純虛函式提供定義,不過函式體必須定義在類的外部,也就是說,不能在類的內部為乙個=0
的函式提供函式體。
含有或者未經覆蓋直接繼承純虛函式的類是抽象基類,抽象基類負責定義介面,而後續的其他類可以覆蓋介面。
不能直接建立乙個抽象基類的物件。
class disc_quote :public quote
;class bulk_quote : public disc_quote
double net_price(std::size_t)const override;
};
各個類控制其物件的初始化過程,bulk_quote
沒有資料成員,但是仍然需要像原來一樣提供乙個接受四個引數的建構函式。該建構函式將實參傳遞給disc_quote
的建構函式,隨後disc_quote
的建構函式將繼續呼叫quote
的建構函式。 純虛函式與抽象基類
純虛函式 c 中可以定義這樣一類函式,這樣的函式可以沒有實現。我們把這樣的函式稱為純虛函式。純虛函式有什麼意義 通過它可以指明乙個虛函式只是提供了乙個可被子型別改寫的介面。純虛函式是在基類中宣告的虛函式,它可以在基類中有定義,而且派生類必須定義自己的實現方法。基類不能生成物件,可以使用指標或者引用派...
虛函式 虛基類 抽象類
一 虛基類 解決二義性,防止雙份拷貝間接基類。否則得用作用域分辨符來區分進行的多個拷貝 將共同基類設定為虛函式,這是從不同的路徑繼承過來的同名資料成員在記憶體中就只有乙個拷貝,同乙個函式名也只有乙個對映。虛基類的宣告是在派生類的定義過程中進行的,語法形式為 class 派生類名 virtual繼承方...
虛函式與抽象基類的應用
include using namespace std 宣告抽象基類shape class shape 虛函式 virtual float volume const 虛函式 virtual void shapename const 0 純虛函式 宣告point類 class point public...