C++虛函數 - 靜態函數能否爲虛函數

1.virtual與靜態函數

C++中,靜態成員函數不能被聲明爲virtual函數。

例如,下面的程序會編譯失敗。

class Test
{
  public:
     // 編譯錯誤:static成員函數不能聲明爲virtual   
     virtual static void fun()  { }
};

同樣地,靜態成員函數也不能被聲明爲const和volatile.
下面的程序也會編譯失敗。

class Test
{
   public:
      // 編譯錯誤: static成員函數不能爲const
      static void fun() const { }
      // 如果聲明爲下面這樣,是可以的。
      const static void fun() {}
      或類似於
      const static int fun() { return 0; }
};

2.爲何static成員函數不能爲virtual

  1. static成員不屬於任何類對象或類實例,所以即使給此函數加上virutal也是沒有任何意義的。

  2. 靜態與非靜態成員函數之間有一個主要的區別。那就是靜態成員函數沒有this指針。

 虛函數依靠vptr和vtable來處理。vptr是一個指針,在類的構造函數中創建生成,並且只能用this指針來訪問它,因爲它是類的一個成員,並且vptr指向保存虛函數地址的vtable.

 對於靜態成員函數,它沒有this指針,所以無法訪問vptr. 這就是爲何static函數不能爲virtual.

 虛函數的調用關係:this -> vptr -> vtable ->virtual function

      3.通過下面例子可以確定,當類增加了一個虛函數後,類的大小會增大4字節(指針的大小).

class Test
{
public:
int _m;
};
sizeof(Test) = 4;

加入虛函數後,

class Test
{
public:

int _m;
virtual void fun();
};
sizeof(Test) = 8

4 .爲何static成員函數不能爲const函數

 當聲明一個非靜態成員函數爲const時,對this指針會有影響。對於一個Test類中的const修飾的成員函數,this指針相當於const Test*, 而對於非const成員函數,this指針相當於Test *.

 而static成員函數沒有this指針,所以使用const來修飾static成員函數沒有任何意義。

 volatile的道理也是如此。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章