程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 實現C++虛函數時相關注意事宜

實現C++虛函數時相關注意事宜

編輯:C++入門知識

C++中的C++虛函數的作用主要是實現了多態的機制,虛函數Virtual Function)是通過一張虛函數表Virtual Table)來實現的,簡稱為V-Table,供大家學習參考!

如果一個類不包含虛函數,這經常預示不打算將它作為基類使用。當一個類不打算作為基類時,將析構函數聲明為虛擬通常是個壞主意。考慮一個表現二維空間中的點的類:

  1. class Point { // a 2D point  
  2.  public:  
  3. Point(int xCoord, int yCoord);  
  4. ~Point();  
  5.  private:  
  6. int x, y;  
  7. };  

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

C++虛函數的實現要求對象攜帶額外的信息,這些信息用於在運行時確定該對象應該調用哪一個虛函數。典型情況下,這一信息具有一種被稱為 vptrvirtual table pointer,虛函數表指針)的指針的形式。

vptr 指向一個被稱為 vtblvirtual 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++虛函數,但是被誤導的程序員有時將它當作基類使用:

  1. SpecialString *pss = new SpecialString("Impending Doom");  
  2.  
  3. std::string *ps;  
  4. ...  
  5. ps = pss; // SpecialString* => std::string*  
  6. ...  
  7. delete ps; // undefined! In practice,  
  8. // *ps’s SpecialString resources  
  9. // will be leaked, because the  
  10. // SpecialString destructor won’t  
  11. // be called.  

一眼看上去,這可能無傷大雅,但是,如果在程序的某個地方因為某種原因,你將一個指向 SpecialString 的指針轉型為一個指向 string 的指針,然後你將 delete 施加於這個 string 指針,你就立刻被送入未定義行為的領地。

  1. C與C++中標准輸入實現方式上的一點區別
  2. C++編譯器如何對Const常量進行分配存儲空間
  3. C++類庫設計的基本構思與方法
  4. 玩轉C++語言的幾種方法
  5. 如何更好的進行C++代碼編制

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved