C 中使用非靜態成員函式代替全域性函式

2021-08-22 17:12:06 字數 1867 閱讀 2125

我們需要一組功能函式,但又不想使用全域性函式,以免汙染命名空間,當然可以使用命令空間,也可以使用靜態成員函式,但我們還有一種另類的方法,使用非靜態成員函式。如下類:

class util

// 我們只用於使用該類組織**,但從不進行例項化

~util(){};

public:

static float version ;

void func(int val) };

float util::version = 1.1f;

以後我們可能這樣呼叫util::func()函式:

util *pa =0;

pa->func(__line__);

或 ((util*)0)->func(__line__);

注意,既然pa是個空指標,則它不指向任何物件,func函式也不能使用任何非靜態成員變數。雖然從工程上講,這樣做的必要性讓人疑,但這樣做的確是可能的。如果把version改為私有變數,好像這樣做會更有意義一些,比如我們可以封裝一些演算法進去,其中可能用到一些常量,但這些常量又不想讓使用者看到,就可以將這些常量定義為私有的靜態成員。無論如何,這種方式,都可以使用靜態成員函式替代,現在還沒有發現這種方式比靜態成員函式比較優秀,如果硬是要提出來一種場景的話,那就是寫一些讓人難以琢磨的**耍酷。其它的真的想不起來了。

再加乙個靜態成員函式:

class util

};看看vc9呼叫這些函式的彙編**

pa->func(__line__);

004116a6 mov eax,dword ptr [`hard_exception_test'::`2'::__line__var (41c010h)]

004116ab add eax,4

004116ae push eax

004116afmov ecx,dword ptr [pa]

004116b2 call util::func (411203h)

((util*)0)->func(__line__);

004116b7 mov eax,dword ptr [`hard_exception_test'::`2'::__line__var (41c010h)]

004116bc add eax,5

004116bf push eax

004116c0xor ecx,ecx

004116c2 call util::func (411203h)

util::func2(__line__);

004116c7 mov eax,dword ptr [`hard_exception_test'::`2'::__line__var (41c010h)]

004116cc add eax,6

004116cf push eax

004116d0 call util::func2 (4110e1h)

還是使用靜態成員函式呼叫更直接一些,因為非靜態函式函式在呼叫時要比靜態成員函式呼叫多傳遞乙個引數--this指標。當在成員函式中用到非靜態成員變數時,就會通過this指標去訪問該變數,但我們前兩種呼叫時this指標指向的非法位址,那樣的話作業系統會丟擲非法訪問的異常,導致程式意外終止。

實際上,檢視彙編**,很清楚,前兩種呼叫是傳遞了this指標的,相當於傳了乙個指標引數,但我們沒有使用該引數,所以不會出現異常。

無論從工程上,還是從效率上講,這種呼叫方式都不及靜態成員函式,但通過這種方式的分析可以更清楚c++類的封裝機制的實現,實際上就是在c++的結構基礎上增加了乙個隱藏的this指標,編譯器為成員函式自動增加了乙個引數,交自動將this指標作為實參傳遞給函式。

程式在vc9及g++ (for cygwin)都通過了,沒有問題。

C 靜態成員函式訪問非靜態成員

如果類沒有被建立,則沒有對應的成員,也就無法訪問 下面這種方法需要先建立類,並將類作為引數傳遞給靜態成員函式才能訪問。include using namespace std class person class student public person static void get age st...

在類的靜態成員函式中使用類的非靜態成員

我們知道,類的靜態成員函式只能訪問類的靜態資料成員和類的其他靜態函式,eg includeusing namespace std class a static void func2 void func3 int main 如果我們要在類的靜態成員函式中使用類的非靜態成員函式和非靜態資料成員時,可以通...

xcode中用靜態成員函式來代替全域性變數

objective c支援全域性變數,用法和c c 中相同。但是當我們要求如下時 如在a類裡面定義的變數,在b類中不需要建立a類的例項就可訪問和修改。用全域性變數來實現並不合適。此時我們需要做的是在a類的implementation檔案中定義一 個static變數,然後為a類定義靜態成員函式 cla...