2014年5月3日 星期六

[C/C++] Static 成員 概念和使用

在使用類別時可以同時生成各個物件時,物件會擁有相同的資料成員
其中有些屬性是共通不需要改變的
例如,寫遊戲時用一個類別專門產生 A 怪物,類別內設定 A 怪物出生地為“神秘洞穴”
當遊戲在大量生成怪物時,不用每隻怪都產生自己的“出生地”資料成員,因為都一樣
所以其實共用“出生地=神秘洞穴”這個資料成員可以達到節省記憶體目的
將資料成員宣告為 static ,被宣告為 static 的資料成員,它是屬於類別所擁有
而不是個別的物件,我們可以將 static 視為個別物件所擁有、共享的資料成員
把可共用的設定成 static 成員,不會造成每次類別生物件,每個資料成員都要複製一次,減少記憶體資源
宣告 static function -->封裝,別份檔案不能呼叫該 function
static 可允許不生成物件,直接利用 class member 或 function
class A
{
public:
 static int data1 ; // static 資料成員,各物件共用 data1
 int data2 ;

 static void setData1() //跟宣告 static 全域變數一樣可達到“封裝”,別份檔案無法呼叫此 function
 {                      //宣告為 static 的成員變數得用 static 的成員函數 ( member function )
  data1 = 77 ;
 }
 void setData2()
 {
  data2 = 500;
 }
};
記得在類別定義外先初始化 static 成員
順便生成一個 a1 物件,方便後面了解記憶體位置
class A
{
...
};

int A::data1 ;
A a1;

int main()
{
...
}
直接存取 static 成員變數
A::data1 = 99;
不生成物件,直接用類別名稱呼叫 static member function
A::setData1();
也可在生成物件之後,以物件名稱加上 '.' 運算子來存取 static 靜態資料成員,但是這個方式不被鼓勵
通常建議使用類別名稱加上 '::' 運算子來存取,一方面也可以避免與非靜態資料成員混淆
a1.data1; /**/
嘗試修改 a1 的 data1 和 data2 成員內容,
a1.setData2();
a1.data1 = 77; //再度強調,這存取 static 成員的方法應避免,應使用 A::data1,這邊僅為練習用
編譯結果,可以看見 data2 被修改成 500,而 data1 因共用關係
記憶體位置與類別下的 A::data1 一樣, A::data1 內容也從 99 改成 77

static 其他功用
用在 local variable -->(改變)增加生命期,讓原有的 scope 結束後,繼續存在到程式結束
用在 global variable -->把 scope 限制在該份 .cpp 檔裡,別份檔不能 link 到他-->封裝

沒有留言:

張貼留言