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
-
static成員不屬於任何類對象或類實例,所以即使給此函數加上virutal也是沒有任何意義的。
-
靜態與非靜態成員函數之間有一個主要的區別。那就是靜態成員函數沒有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的道理也是如此。