1. 程式人生 > >【總結】C++與C#中的static靜態修飾符

【總結】C++與C#中的static靜態修飾符

this sea const 數據 一切都 UC 限制 有一個 字段

重點
  1. 靜態類(sealed+abstract)
  2. 靜態構造函數(無參,無限制符,自動執行一次)
  3. 靜態變量(類級別,實例無關,靜態存儲區中)
  4. 靜態方法(不能被重寫)
  5. 靜態局部變量(始終存在)
靜態本質是實例無關的,表示不會修改實例的 C++ 靜態成員變量
  • 靜態成員 的內存只被分配一次,會一直存在於程序的整個生命周期中
  • 如果要將靜態成員類內初始化,那麽該變量需要聲明為const常量
  • int class :: c = 10; static數據成員可以在類外定義和初始化,也可以在函數中賦值。可以直接由 class::member 訪問,但是不能用 .訪問
靜態成員函數
  • 成員函數、靜態成員函數、虛函數
    在c++中類的成員函數都是保存在靜態存儲區中的,都是通過函數地址來訪問。
  • 不能調用non-static函數,但是可以通過引用傳遞間接調用
  • 為什麽靜態成員函數不能是const?const修飾符用於表示函數不能修改成員變量的值,該函數必須是含有this指針的類成員函數,函數調用方式為thiscall
而類中的static函數本質上是全局函數,不能訪問非靜態成員,const函數表明不會修改實例成員,那麽static就沒意義了 靜態全局變量和函數 修飾全局變量時,表明一個全局變量只對定義在同一文件中的函數可見。 修飾函數時,表明該函數只能在同一文件中調用。 static const 常量+只在當前模塊中可見 C++中const是實例成員,不能在類定義處初始化,不同對象可以不同(構造初始化列表),不能由類名直接訪問
C#中的const是隱式static的,可以由類名直接訪問。C++const更接近於只讀,所以兩者的const是不同的 C# 靜態類
  1. 靜態類的本質,是一個抽象的密封類,所以不能被繼承,也不能被實例化。
  2. 靜態類與非靜態類的重要區別在於靜態類不能實例化,也就是說,不能使用 new 關鍵字創建靜態類類型的變量。也不能有非靜態成員(即實例成員)
  3. 不支持繼承,所以靜態類不能包含protected成員。但是可以實現接口。interface不能是靜態的
  4. 靜態類通常是收集一些常用的方法,與面向對象無關了
執行順序(經過測試) 靜態初始化器-靜態構造函數-初始化器-構造函數 靜態構造函數
  1. 這個類的成員,第一次被訪問之前,會執行靜態構造函數。如類被實例化或者靜態成員被調用的時候進行調用,並且是由.net框架來調用靜態構造函數來初始化靜態成員變量
  2. 靜態構造函數只被執行一次
  3. 靜態構造函數不可被訪問限制符修飾, 因為靜態構造函數不是我們程序員調用的,是由.net 框架在合適的時機調用的。
  4. 靜態構造函數沒有參數,因為框架不可能知道我們需要在函數中添加什麽參數,所以規定不能使用參數。
  5. 一個類中只能有一個靜態構造函數。
  6. 無參數的靜態構造函數和無參數的構造函數是可以並存的。因為他們一個屬於類級別,一個屬於實例級別,並不沖突。
  7. 如果我們在類中定義了靜態變量,但是又沒有定義靜態構造函數,那麽框架也會自動生成一個靜態構造函數以初始化類。
靜態與初始化器
  1. 初始化器:即聲明字段後直接用=賦值
  2. 系統默認的初始化會將會在所有代碼執行前把一切都設置成0或者null,所以這時無需用初始化器
  3. 靜態構造函數在標準構造函數之前運行
靜態成員
  1. 非靜態類可以包含靜態的方法、字段、屬性或事件;
  2. 無論對一個類創建多少個實例,它的靜態成員都只有一個副本;
  3. 靜態方法和屬性不能訪問其包含類型中的非靜態字段和事件,並且不能訪問任何對象的實例變量;
  4. 可以在靜態方法中定義變量並使用,和普通方法一樣
  5. 靜態方法只能被重載,而不能被重寫,因為靜態方法不屬於類的實例成員
  6. 常量本質是靜態的:雖然字段不能聲明為 static const,但 const 字段的行為在本質上是靜態的。這樣的字段屬於類,不屬於類的實例。因此,可以同對待靜態字段一樣使用 ClassName.MemberName 表示法來訪問 const 字段;
  7. 可以用 static readonly(只讀不同於常量)
  8. this/base 關鍵字在靜態方法中不能使用,因為有可能對象還不存在。
  9. 類加載的時候,所有的靜態成員就會被創建在“靜態存儲區”裏面,一旦創建直到程序退出,才會被回收。
註:Person p;  //這樣實際上就已經被加載了。 其他類可以直接 類名.靜態變量名 來訪問,就像靜態類一樣 靜態局部變量 C++ 函數中的局部變量的值在函數調用結束後不消失而保留原值,即其占用的存儲單元不釋放,在下一次該函數調用時,該變量保留上一次函數調用結束時的值。 為靜態局部變量賦初值是在編譯時進行值的,即只賦初值一次,在程序運行時它已有初值。以後每次調用函數時不再重新賦初值而只是保留上次函數調用結束時的值。 C# c#不支持方法內的靜態變量,原因有二。 1. 一般來說方法內的靜態變量可以用該方法所屬類的靜態成員變量代替 2. 方法中的靜態變量會在多線程的應用裏造成不比要的麻煩。 其他 C#:不要把 static 成員變量的初始化動作安排在類的構造函數中,因為構造函數可能一再被調用,而變量的初值卻只應該設定一次。 C++:也不要把初始化動作安排在頭文件中,因為它可能會被包含許多地方,因此也就可能被執行許多次。你應該在實現文件中且類別以外的任何位置設定其初值。例如在 main 之中,或全域函數中,或任何函數之外

【總結】C++與C#中的static靜態修飾符