虛函數的應用特性

 

虛函數的應用特性

         
例:編寫三個類:沒有虛函數、有一個虛函數、有兩個虛函數,在主函數中定義這三個類的對象,分別取這個類所佔的內存空間的大小,觀察在內存中的分配;
          
代碼如下:
         
/**//************************************************************************
* 虛函數的應用特性例子
***********************************************************************
*/

#include 
<iostream.h>
//沒有虛函數的類
class CNoVirtual
...
{    int x;
public
:
    CNoVirtual(
int nx)...{x=nx;}

    
void func() const...{}
    
int GetX() const ...{return x;}
}
;

//有一個虛函數的類

class COneVirtual
...
{    int x;
public
:
    COneVirtual(
int nx)...{x=nx;}

    
virtual void func() const...{}
    
int GetX()...{return x;}
}
;

//有兩個虛函數的類

class CTwoCirtuals
...
{    int x;
public
:
    CTwoCirtuals(
int nx)...{x=nx;}

    
virtual void func() const...{}
    
virtual int GetX() const ...{return x;}
}
;

void
 main()
...
{    CNoVirtual obj1(100);
    COneVirtual obj2(
200
);
    CTwoCirtuals obj3(
300
);
    cout
<<"size of types: "
;
    cout
<<"int         : "<<sizeof(int)<<
endl;
    cout
<<"CNoVirtual  : "<<sizeof(CNoVirtual)<<
endl;
    cout
<<"void*       : "<<sizeof(void*)<<
endl;
    cout
<<"COneVirtual : "<<sizeof(COneVirtual)<<
endl;
    cout
<<"CTwoVirtual : "<<sizeof(CTwoCirtuals)<<
endl;
}
               
              
1. 運行結果:
                      
                  
2. 對象的內存分配情況:
           
    
          
3. 對象的地址及內容:
            
           
4. 對象的成員變量的地址及內容:
        
              
綜上,對象的內存空間分配情況如下:
          
              
說明:
  從上面的結果可以看到,沒有虛函數的類CNoVirtual的大小正好是其成員變量——一個整型數據的大小,而有一個虛函數和兩個虛函數的類的大小還要加上一個緊縮的空指針類型的大小。這說明了在包含虛函數的類中,編譯系統自動加入了一些表明類型的信息。
  當一個類中擁有虛函數時,編譯系統將爲該類創建一個數組VTABLE。VTABLE數組中的元素是虛函數的地址,且同一虛函數的地址在基類和派生類的VTABLE中相對首位置的偏移是一樣的。同時,編譯系統還加入了相應的調用虛函數的代碼。所有這些都是不需要程序員作的工作,由系統自動完成。在初始化該類對象時,將加入一個指向VTABLE的指針,這個指針一般稱爲VPTR。一般來說,VPTR位於該類對象的存儲單元的最開始部位,如上圖所示。
  這樣,當VPTR被正確的初始化之後,便指向了該對象的VTABLE,從而在對象及其特定的虛函數定義間建立了聯繫。從虛函數調用的意義上來說,VPTR表明了類型信息,因爲它使得調用與類型相符合。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章