在C++中,靜態成員函數只能訪問靜態成員,原因在於沒有this指針。這已經是常識了。
其實,成員函數在編譯時,編譯器會自動加上this指針。
比如
A a; a.func(1);
會當做
A::func(&a, 1);
成員函數的原型是
A::func(int);
編譯器處理后等價於
A::func(A* const register this, int) //不要人為添加this聲明,是編譯器隱式生成的,否則報錯
而靜態函數就沒有this這個指針了。
但是有一個問題,最近看面試書,里面提到了有一種設計模式,可將構造函數聲明為private/protected,而后用靜態成員函數調用構造函數。
靜態成員函數調用私有構造函數,嗯。
如何實現呢?為什么能夠行得通呢?
明確一點,靜態成員函數可以訪問靜態成員變量,全局變量,和自身的函數形參。
所以,可以將對象做為static函數的形參傳遞進去
比如
static void A::Instance(A * const pa);
而且,在靜態函數Instance中,可以訪問A的成員
void A::Instance(A * const pa) { pa->func(); //func可以是非靜態成員函數,而且無論private 還是protected pa->a; //可以訪問非靜態成員變量,無論private還是protected }
抑或在Instance中new一個A對象
class A { public: static A* Instance(); protected: A(); private: static A* _instance; } //實現時 A* A::_instance = NULL; A* A::Instance() { if( _instance == NULL ) { _instance = new A(); } return _instance; }
不管是哪種方案,都是顯式在靜態函數中引入了一個對象。
同時,我們注意到,static函數內部可以通過一個對象a,來無差別權限地訪問各個成員函數和變量。
這里涉及到一個作用域的問題。靜態成員函數也是成員函數,所以在函數開頭有A::來表明作用域,那么就可以在其中訪問A的成員函數和變量。
看來一個成員函數有兩點需要我們注意,一個是this指針,還有一個就是作用域。
上文所描述的,是設計模式中的單件模式,很巧妙的應用哈~