近來看了侯捷的《深入淺出mfc》,讀到c++重要性質中的虛函式與多型那部分內容時,頓時有了疑惑。因為書中說了這麼一句:使用「基類之指標」指向「派生類之物件」,由該指標只能呼叫基類所定義的函式,如果要讓基類的指標使用派生類中定義的函式,就將該函式定義為虛函式。
但在「object slicing與虛函式」這一小節給出了乙個及其經典的例子,它指出,在向上(即向基類)強制轉型時,會造成物件內容的被切割。
下面用示例進行說明:
#include "stdafx.h"
#include using namespace std;
class a
結果如下:
通過除錯分析其記憶體模型如下:
可知,通過a a1=(a)b1傳值時,物件中指向虛函式表的指標__vfptr值不同,但是通過a *a2=(a*)&b1傳址操作時,物件中指向虛函式表的指標__vfptr值是相同的,呼叫的是類b物件的虛函式表中虛函式fn()。注意,物件呼叫的是哪個類的虛函式就要看類物件的虛函式表中的函式是哪乙個。這句話也好理解,a1虛函式表中fn()是a::fn(),a2虛函式表中fn()是b::fn(),所以出現以上結果。
在如下包含父類的父類的繼承中:
class a;
c c;
a a1=(c)c;
a * a2=(c*)&c;
a1.fn();
a2->fn();
這時,a1虛函式表中fn()為a::fn(),a2虛函式表中fn()為b::fn(),因為類c物件的虛函式表中fn()為b::fn(),a2中指向虛函式表的指標值與類c物件指向虛函式表的指標值相同。
侯捷的書中有句話是這麼對它進行解釋的:由於(a)b1.fn()是傳值而非傳位址操作,編譯器以所謂的拷貝建構函式把a物件內容複製了乙份,使得b1的虛函式表內容與a物件的虛函式表內容相同。
看來,得多讀聖賢書啊,讀懂讀透啊!
虛函式 與派生類遮蔽基類函式
class base public virtual void print void cout 10public void print int i cout base iter new dervied iter print 5 基類指標會在基類物件中尋找函式,找到函式名後,判斷引數,沒有乙個引數的,所...
基類和派生類,虛函式
基類負責定義在層次關係中所有類共同擁有的成員,而每個派生類定義各自持有的成員。基類希望它的派生類各自定義適合自身的版本,此時基類就將這些函式宣告成虛函式。class quote 派生類必須通過使用類派生列表明確指出它是哪個基類繼承而來。類派生列表的形式 首先是乙個冒號,後面緊跟以逗號分隔的基類列表,...
派生類與基類間的轉化
派生類到基類 呼叫函式時 將派生類物件傳遞給希望接受基類引用的函式,此時並不發生派生類到基類的型別轉化。因為引用直接繫結到派生類上,物件並沒有複製,只是將派生類的基類部分的位址傳遞給基型別的引用。將派生類物件傳遞給接受基類物件 並非它的引用 的函式時,形參型別是固定的,只是用派生類物件中的基類部分初...