static成員函式不能被宣告為const virtual volatile 原因
阿新 • • 發佈:2019-02-01
1.virtual與靜態函式
C++中,靜態成員函式不能被宣告為virtual函式。
例如,下面的程式會編譯失敗。
#include<iostream>
class Test
{
public:
// 編譯錯誤:static成員函式不能宣告為virtual
virtual static void fun() { }
};
同樣地,靜態成員函式也不能被宣告為const和volatile.
下面的程式也會編譯失敗。
#include<iostream>
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
通過下面例子可以確定,當類增加了一個虛擬函式後,類的大小會增大4位元組(指標的大小).
class Test
{
public:
int _m;
};
sizeof(Test) = 4;
加入虛擬函式後,
class Test
{
public:
int _m;
virtual void fun();
};
sizeof(Test) = 8
3.為何static成員函式不能為const函式
當宣告一個非靜態成員函式為const時,對this指標會有影響。對於一個Test類中的const修飾的成員函式,this指標相當於Test const *, 而對於非const成員函式,this指標相當於Test *.
而static成員函式沒有this指標,所以使用const來修飾static成員函式沒有任何意義。
volatile的道理也是如此。
public:
int _m;
virtual void fun();
};
sizeof(Test) = 8
volatile 與const類似 ,volatile的作用是作為指令關鍵字,確保本條指令不會因編譯器的優化而省略,且要求每次直接讀值。