第乙個問題,靜態成員函式是放在記憶體中的哪個位置的?
要回答這個問題,首先對c++記憶體機制做乙個簡單的介紹。
c++程式的記憶體格局通常分為四個區:全域性資料區(data area),**區(code area),棧區(stackarea),堆區(heap area)(即自由儲存區)。全域性資料區存放全域性變數,靜態資料和常量;所有類成員函式和非成員函式**存放在**區;為執行函式而分配的區域性變數、函式引數、返回資料、返回位址等存放在棧區;餘下的空間都被稱為堆區。根據這個解釋,我們可以得知在類的定義時,類成員函式是被放在**區,而類的靜態成員變數在類定義時就已經在全域性資料區分配了記憶體,因而它是屬於類的。對於非靜態成員變數,我們是在類的例項化過程中(構造物件)才在棧區或者堆區為其分配記憶體,是為每個物件生成乙個拷貝,所以它是屬於物件的。
[靜態成員函式首先是成員函式,所以其與普通成員函式均放置在**區。既然放置在**區,那麼可以得到乙個結論,如果沒有呼叫到類的普通成員變數,那麼在類例項化之前,所有的成員函式均可被類直接呼叫。(注意必須沒有呼叫普通成員變數。因為普通成員變數是要在例項化的時被放在棧區的)
實驗**如下:
#include
using
namespace
std;
class d
static
void printb()
};int main(void)
實驗結果如圖:
由於類的指標為null,所以並沒有為其分配記憶體。但仍可呼叫成員函式。因為他們的記憶體是在**區,生命週期與類相同。所以可以直接呼叫。
第二個問題,靜態成員函式與普通成員函式的區別
最明顯的區別是,靜態成員函式沒有this指標,而普通成員函式有this指標。
this指標有什麼用途呢?
首先,我們都知道類的成員函式可以訪問類的資料(限定符只是限定於類外的一些操作,類內的一切對於成員函式來說都是透明的),那麼成員函式如何知道哪個物件的資料成員要被操作呢,原因在於每個物件都擁有乙個指標:this指標,通過this指標來訪問自己的位址。注:this指標並不是物件的一部分,this指標所佔的記憶體大小是不會反應在sizeof操作符上的。this指標的型別取決於使用this指標的成員函式型別以及物件型別(
每乙個類會生成很多物件,每個物件在不同的記憶體區域中。當物件呼叫成員函式時,成員函式如何找到該物件的記憶體位址呢?這裡就需要this指標。普通成員函式因為隱含了this指標,所以可以隨意訪問成員變數。而靜態成員函式沒有了this指標,所以並不能夠直接操作普通成員變數,必須通過傳參的方式,告訴靜態成員函式物件的位址,才能夠操作普通成員變數。 靜態成員函式省略了this指標,使得他在操作普通成員變數有諸多困難,那麼為什麼要設計這種函式呢?原因在於,擁有了this指標,就要跟具體的物件掛鉤;沒有了this指標,該函式就可以跳出具體的物件,而作為不同的物件之間通訊的工具。舉個例子,在設計鍊錶時,如果用物件導向的方法,我們更希望將操作頭指標的函式封裝在類裡面。這時用靜態成員函式操作靜態成員變數,就會使頭指標的操作更為便利,美觀。 回到之前的**,普通成員函式可以直接用類來呼叫(如果該普通成員函式沒有呼叫普通成員變數),但我認為c++這樣的處理有點理論上不完美。也許後續的學習可以讓我對此更加了解。
C 靜態成員與靜態成員函式小結
一 靜態資料成員 類體中的資料成員的宣告前加上static關鍵字,該資料成員就成為了該類的靜態資料成員。和其他資料成員一樣,靜態資料成員也遵守public protected private訪問規則。同時,靜態資料成員還具有以下特點 1.靜態資料成員的定義。靜態資料成員實際上是類域中的全域性變數。所...
C 靜態成員與靜態成員函式小結
類中的靜態成員真是個讓人愛恨交加的特性。我決定好好總結一下靜態類成員的知識點,以便自己在以後面試中,在此類問題上不在被動。靜態類成員包括靜態資料成員和靜態函式成員兩部分。一 靜態資料成員 類體中的資料成員的宣告前加上static關鍵字,該資料成員就成為了該類的靜態資料成員。和其他資料成員一樣,靜態資...
C 靜態成員函式小結
一 靜態資料成員 1.靜態資料成員的定義 2.靜態資料成員被 類 的所有物件所共享 包括該類派生類的物件 3.靜態資料成員可以成為成員函式的可選引數 普通資料成員則不可以 4.靜態資料成員的型別可以是所屬類的型別 普通資料成員則不可以 5.靜態資料成員的值在 const 成員函式中可以被合法的改變 ...