1. 程式人生 > >c++中,可以用類名直接訪問非靜態成員函式?

c++中,可以用類名直接訪問非靜態成員函式?

正規的C++語言標準目前(截止到C++14)應該還不支援這種呼叫方法。
目前微軟似乎在它的VC++中推行一種叫做C++/CLI的標準,有可能會支援這種呼叫,如果一定要用這種呼叫方法的話,還應該用VS2013嘗試編譯執行一下。

實際上,C++語言中類的靜態成員函式本身應該是所有這一類物件的集體所具有的行為,就是說,不是某一個物件能夠具有或者說實現的;而非靜態成員函式應該是某一個物件自己的動作行為,跟本類其他物件乃至整個類關係不大,是物件依靠自己的資料以及函式引數就可以完成的行為。
根據以上的討論,我們可以看出,很難存在一種需求,使得一個成員函式不需要引用本物件的非靜態成員,同時又必須是一個物件自己的行為(即宣告為非靜態成員函式)。如果真的存在不引用非靜態成員的成員函式,那還是直接宣告為靜態成員函式為好,這樣就可以萬無一失地通過編譯,也避免了移植性問題。

說句題外話,非靜態成員函式總會有一個隱含的引數,就是this指標。通過反彙編分析也可以發現,非靜態成員函式的呼叫屬於特殊的thiscall,就是說總會傳入一個this指標。而靜態成員函式和類外的函式一樣,經過編譯後都是普通的呼叫,不會得到this指標,因此也不可能訪問非靜態成員(因為非靜態成員的引用總是通過this指標完成的)。因此一個函式能否通過類名呼叫,主要還是要看它是否需要編譯器傳入this指標(要看編譯後的程式碼,原始碼級別上的呼叫是看不到傳入的this指標的)。

如果真的希望在沒有例項的前提下,呼叫一個非靜態成員函式,可以使用下面的方法(前提是必須符合您提出的那個條件,即不訪問任何非靜態成員,如果它訪問了非靜態成員,則可能導致記憶體讀寫異常):

// 假設要引用的類型別為 TargetType, 成員函式為 void TargetType::TargetFunc();
// C++11 版:
static_cast<TargetType *>(nullptr)->TargetFunc();
// C++98/03 版:
reinterpret_cast<TargetType *>(0)->TargetFunc();
// 如果使用 C 風格的型別轉換操作符:
((TargetType *) 0)->TargetFunc();