溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

實現(xiàn)C++虛函數(shù)時的注意事宜有哪些

發(fā)布時間:2021-10-27 18:19:36 來源:億速云 閱讀:303 作者:柒染 欄目:編程語言

實現(xiàn)C++虛函數(shù)時的注意事宜有哪些,針對這個問題,這篇文章詳細介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

C++中的C++虛函數(shù)的作用主要是實現(xiàn)了多態(tài)的機制,虛函數(shù)(Virtual Function)是通過一張?zhí)摵瘮?shù)表(Virtual Table)來實現(xiàn)的,簡稱為V-Table,供大家學習參考!

如果一個類不包含虛函數(shù),這經(jīng)常預(yù)示不打算將它作為基類使用。當一個類不打算作為基類時,將析構(gòu)函數(shù)聲明為虛擬通常是個壞主意??紤]一個表現(xiàn)二維空間中的點的類:

class Point { // a 2D point   public:  Point(int xCoord, int yCoord);  ~Point();   private:  int x, y;  };

如果一個 int 占 32 位,一個 Point 對象正好適用于 64 位的寄存器。而且,這樣一個 Point 對象可以被作為一個 64 位的量傳遞給其它語言寫的函數(shù),比如 C 或者 FORTRAN。如果 Point 的析構(gòu)函數(shù)是虛擬的,情況就完全不一樣了。

C++虛函數(shù)的實現(xiàn)要求對象攜帶額外的信息,這些信息用于在運行時確定該對象應(yīng)該調(diào)用哪一個虛函數(shù)。典型情況下,這一信息具有一種被稱為 vptr(virtual table pointer,虛函數(shù)表指針)的指針的形式。

vptr 指向一個被稱為 vtbl(virtual table,虛函數(shù)表)的函數(shù)指針數(shù)組,每一個包含C++虛函數(shù)的類都關(guān)聯(lián)到 vtbl。當一個對象調(diào)用了虛函數(shù),實際的被調(diào)用函數(shù)通過下面的步驟確定:找到對象的 vptr 指向的 vtbl,然后在 vtbl 中尋找合適的函數(shù)指針。

虛函數(shù)如何被實現(xiàn)的細節(jié)是不重要的。重要的是如果 Point 類包含一個虛函數(shù),這個類型的對象的大小就會增加。在一個 32 位架構(gòu)中,它們將從 64 位(相當于兩個 int)長到 96 位(兩個 int 加上 vptr);

在一個 64 位架構(gòu)中,他們可能從 64 位長到 128 位,因為在這樣的架構(gòu)中指針的大小是 64 位的。為 Point 加上 vptr 將會使它的大小增長 50-100%!Point 對象不再適合 64 位寄存器。而且,Point 對象在 C++ 和其他語言(比如 C)中。

看起來不再具有相同的結(jié)構(gòu),因為其它語言缺乏 vptr 的對應(yīng)物。結(jié)果,Points 不再可能傳入其它語言寫成的函數(shù)或從其中傳出,除非你為 vptr 做出明確的對應(yīng),而這是它自己的實現(xiàn)細節(jié)并因此失去可移植性。

這里的基準就是不加選擇地將所有析構(gòu)函數(shù)聲明為虛擬,和從不把它們聲明為虛擬一樣是錯誤的。實際上,很多人總結(jié)過這條規(guī)則:當且僅當類中至少包含一個虛擬函數(shù)時,則聲明一個虛析構(gòu)函數(shù)。

但是,當完全沒有C++虛函數(shù)時,就可能和非虛析構(gòu)函數(shù)問題發(fā)生撕咬。例如,標準 string 類型不包含C++虛函數(shù),但是被誤導的程序員有時將它當作基類使用:

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 的指針轉(zhuǎn)型為一個指向 string 的指針,然后你將 delete 施加于這個 string 指針,你就立刻被送入未定義行為的領(lǐng)地。

關(guān)于實現(xiàn)C++虛函數(shù)時的注意事宜有哪些問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

c++
AI