1、什麼是虛函式?
虛函式是在類中由virtual關鍵字宣告的成員函式,並且每乙個含有虛函式的類都會至少有乙個與之對應的虛函式表,用來存放該類所有虛函式對應的函式指標。
所有虛函式位址都會存放在所屬類的虛函式表中,子類會繼承父類的虛函式表,若是子類中有與父類相同的虛函式,則會構成重寫,此時子類的虛函式指標將會覆蓋父類的虛函式指標,若子類中有新增的虛函式,則也會按順序新增在子類的虛函式表中。
2、虛函式表是如何構造和繼承的
(1)基類虛函式表的構造
在基類宣告中找到所有的虛函式,按照宣告順序進行編碼,然後按照編碼順序為基類構建乙個虛函式表,虛函式表中的內容就這這些指向這些虛函式的函式指標。
(2)子類中虛函式表的構建與繼承
首先將基類中的虛函式表複製到子類的虛函式表指標中,若子類重寫了基類的虛函式,則將子類中的虛函式表中對應的虛函式的函式指標更新為子類的虛函式的函式指標,若子類中有新增的虛函式,則將新增虛函式的函式指標新增找虛函式表的後面。
3、虛函式的實現機制
乙個類**現虛函式,就會產生相應的虛函式表,來存放指向虛函式的函式指標,如果乙個子類繼承基類,那麼首先將基類中的虛函式表複製到子類的虛函式表指標中,若子類重寫了基類的虛函式,則將子類中的虛函式表中對應的虛函式的函式指標更新為子類的虛函式的函式指標,若子類中有新增的虛函式,則將新增虛函式的函式指標新增找虛函式表的後面, 所以這樣通常只有在執行程式時才能確定物件的型別。由此說明編譯器對虛函式的使用動態聯編。
4、動態聯編與靜態聯編
靜態聯編:在程式編譯期間已經確定了程式的行為。比如:函式過載
動態聯編:在程式執行期間才能確定程式的行為以及呼叫的函式
5、多型
多型就是指不同的物件完成同一行為時會產生不同的狀態。
6、多型的產生條件
必須通過基類的指標或者引用呼叫虛函式;
被呼叫的函式必須是虛函式(有virtual關鍵字);
派生類必須對基類的虛函式進行重寫(函式名、返回值型別、引數列表均相同)。
7、為什麼要將析構函式定義成虛函式
因為子類的成員是有兩部分構成,一部分是繼承自父類的成員,一部分是自己定義的,如果析構函式不定義成虛函式,則子類的析構函式只能析構自己定義的這一部分,而繼承自父類的成員是無法析構的,這樣就會造成只析構一部分的情況,會造成資源洩漏,所以要將析構函式定義成虛函式。
8、哪些函式不能是虛函式,並說明理由?
(1)inline函式:因為inline函式沒有位址,無法把位址放到虛函式表中。
(2)靜態成員函式:因為靜態成員函式沒有this指標,使用型別::成員函式的呼叫方式無法訪問虛表,所以靜態成員函式無法放進虛函式表。
(3)建構函式:因為物件中的虛函式表指標是在建構函式初始化列表階段才初始化的。
9、如果在構造函式呼叫乙個類的虛函式會發生什麼?
這樣可能會出現問題,因為物件的構造是從基類開始構造,然後才是派生類。所以,如果呼叫的是繼承類的虛函式的話,此虛函式將訪問乙個未被完全構造的物件
10、 物件訪問普通函式快還是虛函式更快?
首先如果是普通物件,是一樣快的。如果是指標物件或者是引用物件,則呼叫的普通函式快,因為構成多型,執行時呼叫虛函式需要到虛函式表中去查詢。
虛函式相關討論
下列關於虛函式相關說法正確的有?1 多型是通過虛表實現的 2 建構函式可以宣告為虛函式 x 3 析構函式不可以宣告為虛函式 x 4 抽象類中至少包含乙個純虛函式 c 中 的虛函式的作用主要是實現了多型的機制。而虛函式是通過虛函式表 v table 實現的。建構函式為什麼不能宣告為虛函式?1 構造乙個...
C 虛函式相關
c 的封裝 繼承和多型三大特性,封裝沒什麼好說的,就是把事務屬性和操作抽象成為類,在用類去例項化物件,從而物件可以使用操作 管理使用它的屬性。至於繼承,和多型密不可分。基類可以進行派生,而派生類則是繼承基類或稱父類,把基類中屬性和方法拿過來,變成自己的一部分,其中需要較為精細的思考。多型則是一種實現...
建構函式,析構函式和虛函式相關問題
要了解這個話題,首先我們給出一段 include using namespace std class animal virtual void eat void eat int main 執行結果如下 包含虛函式的物件有以下的結構 當基類中的資料成員是private型別的,繼承類的物件無法直接訪問資料...