c++虛函數與虛函數表原理

1.什麼是虛函數?

virtual 修飾的成員函數叫虛函數

小知識: 沒有虛構造函數        不寫虛函數,沒有默認的虛函數

普通函數不影響類的內存:

class MM
{
public:
    void print() 
 {
  cout << "普通函數"<< endl;    //普通函數不影響類的內存<--->普通函數存在另一段內存中
 }
protected:
};

void testVirtual()
{
 //C語言不允許存在空的結構體
 cout << sizeof(MM) << endl;/*(沒有數據成員的)空的類或者結構體 占用1字節  用1字節標識當 
                                   前內存為結構體內存*/
}
int main() 
{
 testVirtual();
 return 0;
}
/*輸出*/

/* 1 */

2.虛函數會影響類的內存

增加一個指針的內存,32位操作系統多4個字節 ,64位操作系統多8個字節

#include <iostream>
using namespace std;
class MM
{
public:
 virtual void print1() 
 {
  cout << "虛函數1"<< endl;
 }
 /*virtual void print2()
 {
  cout << "虛函數2" << endl;
 }     無論多少個虛函數,增加的字節就是一個指針的字節--->多瞭一個虛函數,還是4個字節*/
protected:
};
void testVirtual()
{
 
 cout << sizeof(MM) << endl;  
 
}
int main() 
{
 testVirtual();
 return 0;
}
/*輸出*/

/*  4  */

小知識:一旦有瞭數據,標識位就不需要存在瞭

class A
{
 int num;    //輸出4而不是5   (4+1)
};
class B
{
    //用1字節標識當前內存為結構體內存
};
void testVirtual()
{

 cout << sizeof(A) << endl;
    cout << sizeof(B) << endl;
}
int main()
{
 testVirtual();
 return 0;
}

/*輸出*/

/*4
  1*/

3.瞭解虛函數表—>通過虛函數表的指針去訪問數據

就是一個指針存儲所有虛函數的首地址(虛函數函數名)<—>函數指針

隻有指針可以操作一段內存(4字節)

/*無論多少個虛函數,增加的字節就是一個指針的字節*/
所有的虛函數其實是 用一個函數指針去存儲的 ,把 這個函數指針指向的這一段內存 稱為虛函數表

#include <iostream>
using namespace std;
class MM
{
public:
 virtual void print1() 
 {
  cout << "虛函數1"<< endl;
 } 
    virtual void print2() 
 {
  cout << "虛函數2"<< endl;
 } 
protected:
};
void testVirtual()
{
//虛函數表  
 MM mm;    //構建一個對象
 int** vptr = (int** )&mm;    //定義一個二級指針&對象的地址  強轉類型
 typedef void(*PF)();         //函數指針定義別名
 PF func = (PF)vptr[0][0];    //把地址轉為函數指針,訪問第一個函數指針的地址

 func();  //通過虛函數表的函數指針調用第一個虛函數
 func = (PF)vptr[0][1];
 func();  //調用第二個虛函數
}
int main() 
{
 testVirtual();
 return 0;
}
/*輸出*/

/*虛函數1
  虛函數2*/

4.虛函數聲明

虛函數可以在類中聲明,在類外實現,不再需要virtual修飾詞,隻要類名限定就可以瞭

class MM
{
public:
 virtual void print3();
  
protected:
};
void MM::print3() {
 cout << "虛函數3" << endl;

}
int main()
{
 MM mm;
 mm.print3();
 return 0;
}
/*輸出*/

/*虛函數3*/

到此這篇關於c++虛函數與虛函數表原理的文章就介紹到這瞭,更多相關c++虛函數與虛函數表內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: