靜態變數和靜態函式

2021-06-27 11:16:57 字數 3370 閱讀 5743

靜態變數:

靜態變數使用 static 修飾符進行宣告

在所屬類被裝載時建立

通過類進行訪問

所屬類的所有例項的同一靜態變數都是同乙個值

非靜態變數:

不帶有 static 修飾符宣告的變數稱做非靜態變數

在類被例項化時建立

通過物件進行訪問

同乙個類的不同例項的同一非靜態變數可以是不同的值

在c#中,我們訪問靜態成員用的是類名+成員名稱,而我們在訪問例項成員的時候必須是物件名稱+成員名稱來進行訪問。靜態成員都是需要初始化的,即使你沒有例項化物件也會被例項化,比如:

public static int count;

因為靜態成員是clr組織載入的。因此你不賦值,系統也會預設給你初始化,這裡就是0了。而例項成員是在例項化物件後才被clr載入的。

現在來看下副本的問題,當然就是儲存的位置。那麼什麼是副本呢,msdn裡說的讓人很難理解,因此我一開始根本不理解,總以為是有多個版本,但根本不是這個樣子的。我們知道物件導向就是面向自然界的萬物,那麼乙個類就是乙個真實的存在。那麼它就是乙個原版咯,然後你建的每個物件就是他的例項,也就是他的乙個副本。這樣就好理解了。

如果多個人訪問乙個頁面,那麼將會例項化多個物件。而這多個物件雖然可能是一樣的,但是在記憶體中儲存的位置是不一樣的,這樣就做到了相互之間物件不會發生衝突。而靜態變數則是不管你多少個來訪問,他的值一旦初始化就不會改變,很多例項用的物件都是一致的,因此可以公用。我們再看,比如我例項化了乙個物件,裡面有靜態成員,也有例項成員,但是你訪問這個物件卻不能訪問靜態成員。

那麼靜態成員是怎麼訪問的呢?我們知道,clr在分配記憶體時,根據物件的大小在記憶體中劃分一段區域,跟作業系統是相似的。clr在引導程式時,發現編譯器已經標記了這個靜態變數,然後就在記憶體中這個應用程式域中分配出了一段區域來儲存該靜態變數,當然就是靜態儲存區了。因為這個靜態變數儲存在程式集的區域內,那麼只要程式存在,即使這個類沒有了,這個靜態變數依然存在。然後在記憶體中也存在另一副本,起到引用的作用,當我們在訪問該變數的時候,通過訪問這個副本,然後副本指向這塊記憶體區域位置。

例項成員的儲存也是這樣的,類在例項化乙個物件的時候,就在記憶體中就會為其分配一段區域,以後每生成乙個物件,就繼續劃分區域,乙個接乙個的排列。當我們訪問裡面的例項成員的時候就通過該物件來訪問就可以了。

c#靜態成員和例項成員

c#中類的成員要麼是靜態的,要麼是非靜態的。如果將類中的某個成員宣告為static,則該成員是靜態成員,否則為例項成員。

類的靜態成員是屬於類所有,不必產生類的例項就可以訪問它(而且即便是產生了類的例項,也不能夠通過該例項來訪問類的靜態成員),為類的所有例項所共享,無論這個類建立了多少個例項,乙個靜態成員在記憶體中只占有一塊區域。

類的例項成員屬於類的例項所有,每建立乙個類的例項,都在記憶體中為例項成員開闢了一塊區域。

例如: 

複製**

**示例:

using system;

public class statictest

public void display()

:count=",number,count);}

}class maintest

}執行結果:

object=1:count=1

object=1:count=2

object=2:count=2

靜態成員與例項成員

在類的成員的型別或者返回值型別前面加上關鍵字static,就能將該成員定義為靜態成員(static member)。常量或型別宣告會隱式地宣告為靜態成員,其他沒有用static修飾的成員都是例項成員(instance member)或者稱為非靜態成員。靜態成員屬於類,被這個類的所有例項所共享;例項成員屬於物件(類的例項),每乙個物件都有例項成員的不同副本。

靜態成員具有下列特徵:

— 靜態成員必須通過類名使用 . 運算子來引用,而不能用物件來引用。

— 乙個靜態欄位只標識乙個儲存位置。無論建立了乙個類的多少個例項,它的靜態欄位在記憶體中都只佔同一塊區域。

— 靜態函式成員(方法、屬性、事件、運算子或建構函式)不能作用於具體的例項,在這類函式成員中不能直接使用例項成員,必須通過類名來引用。

例項成員具有以下特點:

— 例項成員必須通過物件名使用 . 運算子來引用,而不能用類名來引用。

— 類的例項字段屬於類的例項所有,每建立乙個類的例項,都在記憶體中為例項字段開闢了一塊區域。類的每個例項分別包含一組該類的所有例項欄位的副本。

— 例項函式成員(方法、屬性、索引器、例項建構函式或析構函式)作用於類的給定例項,在它們的**體內可以直接引用類的靜態和例項成員。

其實,我們在前面的幾章中大量使用的console類的writeline等方法都是靜態方法,都是通過類名console來引用的。

理解下面的**,體會靜態成員和例項成員的使用方法:

複製**

**示例:

class test

static void g() // 靜態方法

static void main()       // 靜態方法

}注意:上述**中,main也是test類的靜態方法,可以在其中直接使用靜態成員,而不需要使用類名來引用。

以下**演示了靜態欄位的性質:

複製**

**示例:

// staticmember.cs

// 靜態欄位的例子

using system;

public class count

public void show()

: count=", number, count);

}}class test

}輸出結果:

object1 : count=1

-----------------

object1 : count=2

object2 : count=2

-----------------

object1 : count=3

object2 : count=3

object3 : count=3

說明:類的所有例項的靜態欄位count的值都是相同的,乙個例項改變了它的值,其他例項得到的值也將隨之變化,說明所有例項都使用同乙個count欄位;而每個例項的成員欄位number的值都是不同的,也不能被其他的例項化改變。

關於c#類的靜態成員與例項變數的內容,就介紹這些吧,希望對大家有所幫助。

靜態類是不能例項化的,我們直接使用它的屬性與方法,靜態類最大的特點就是共享。

** public static class statictestclass}

只要 statictestclass 沒有被重新編譯,即使 p1.aspx、p2.aspx 被重新編譯,每當呼叫 statictestclass.add(),n 都會在前乙個次的基礎上加 1。

原則 靜態建構函式

靜態函式和靜態變數

記憶體大致可以劃分為 棧區堆區 全域性 靜態區 常量區 區 其中棧區位於高位址,區位於低位址。區 存放程式 段 常量區 存放各種常量 數值常量和字串常量等 全域性 靜態區 存放全域性變數和靜態變數,未初始化的和初始化的分開存放 堆區 使用new就是在該區申請 棧區 存放區域性變數等 a.件 clas...

c c 靜態變數和靜態函式

c語言中需要記憶體來存放資料。而記憶體主要分為兩類 靜態儲存區和動態儲存區 靜態儲存區分為 唯讀資料 readonly data 區 以讀寫資料 rw data 區 未初始化區 bss 它們都是在程式編譯連線階段確定的,在程式執行的階段不會改變。動態儲存區分為堆和棧。都是程式執行的過程中動態分配的,...

JS靜態變數和靜態函式

function a 在建構函式外定義的都是所有物件共享的 a.id 我是a a.sayid function a.sayid 如上,在建構函式外用函式名定義的屬性或者方法,可以也只可以通過函式名來訪問,這和c 基本一樣。輸出 試圖訪問非靜態變數時 function a 在建構函式外定義的都是所有物...