您好,登錄后才能下訂單哦!
實現C++虛函數時的注意事宜有哪些,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
C++中的C++虛函數的作用主要是實現了多態的機制,虛函數(Virtual Function)是通過一張虛函數表(Virtual Table)來實現的,簡稱為V-Table,供大家學習參考!
如果一個類不包含虛函數,這經常預示不打算將它作為基類使用。當一個類不打算作為基類時,將析構函數聲明為虛擬通常是個壞主意。考慮一個表現二維空間中的點的類:
class Point { // a 2D point public: Point(int xCoord, int yCoord); ~Point(); private: int x, y; };
如果一個 int 占 32 位,一個 Point 對象正好適用于 64 位的寄存器。而且,這樣一個 Point 對象可以被作為一個 64 位的量傳遞給其它語言寫的函數,比如 C 或者 FORTRAN。如果 Point 的析構函數是虛擬的,情況就完全不一樣了。
C++虛函數的實現要求對象攜帶額外的信息,這些信息用于在運行時確定該對象應該調用哪一個虛函數。典型情況下,這一信息具有一種被稱為 vptr(virtual table pointer,虛函數表指針)的指針的形式。
vptr 指向一個被稱為 vtbl(virtual table,虛函數表)的函數指針數組,每一個包含C++虛函數的類都關聯到 vtbl。當一個對象調用了虛函數,實際的被調用函數通過下面的步驟確定:找到對象的 vptr 指向的 vtbl,然后在 vtbl 中尋找合適的函數指針。
虛函數如何被實現的細節是不重要的。重要的是如果 Point 類包含一個虛函數,這個類型的對象的大小就會增加。在一個 32 位架構中,它們將從 64 位(相當于兩個 int)長到 96 位(兩個 int 加上 vptr);
在一個 64 位架構中,他們可能從 64 位長到 128 位,因為在這樣的架構中指針的大小是 64 位的。為 Point 加上 vptr 將會使它的大小增長 50-100%!Point 對象不再適合 64 位寄存器。而且,Point 對象在 C++ 和其他語言(比如 C)中。
看起來不再具有相同的結構,因為其它語言缺乏 vptr 的對應物。結果,Points 不再可能傳入其它語言寫成的函數或從其中傳出,除非你為 vptr 做出明確的對應,而這是它自己的實現細節并因此失去可移植性。
這里的基準就是不加選擇地將所有析構函數聲明為虛擬,和從不把它們聲明為虛擬一樣是錯誤的。實際上,很多人總結過這條規則:當且僅當類中至少包含一個虛擬函數時,則聲明一個虛析構函數。
但是,當完全沒有C++虛函數時,就可能和非虛析構函數問題發生撕咬。例如,標準 string 類型不包含C++虛函數,但是被誤導的程序員有時將它當作基類使用:
SpecialString *pss = new SpecialString("Impending Doom"); std::string *ps; ... ps = pss; // SpecialString* => std::string* ... delete ps; // undefined! In practice, // *ps’s SpecialString resources // will be leaked, because the // SpecialString destructor won’t // be called.
一眼看上去,這可能無傷大雅,但是,如果在程序的某個地方因為某種原因,你將一個指向 SpecialString 的指針轉型為一個指向 string 的指針,然后你將 delete 施加于這個 string 指針,你就立刻被送入未定義行為的領地。
關于實現C++虛函數時的注意事宜有哪些問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。