2017年5月26日 星期五

static function or static member 用途整合整理

static function or static member 用途整合整理

非類別

static variable

有兩種用途,一種是在 function() 內的靜態變數,一種是全域的靜態變數

全域內的靜態變數

可以有效的隔絕變數被其他檔案使用,如果你有多份檔案
  • a.cpp
  • b.cpp
那麼被設置為 static 的全域變數只有那一份檔案可以使用,如果沒有設置為 static 那麼其他檔案可以透過 extend 來使用、取得。

函式內的靜態變數

該函式的生命週期會延遲到整個程式結束
函式內的變數在函式呼叫結束的時候會清除所有變數,妳果你希望某個函式可以計數,總共被呼叫幾次,可以宣告一個靜態變數,每次都加1。
void fun(){
    static itn i;
    ++i;
}

靜態的函式

保護函式不會被其他cpp檔案存取
與全域變數差不多,禁止其他檔案存取這個函式
static void fun(){;
}
如此一來只有該份 .cpp 檔案可以存取使用這個函式

類別

類別內的靜態變數成員

不管宣告幾個物件,他還是同一個,可以連結所有物件
簡單來說創建了兩個物件 a 與 b ,現在由 a 把他設定為 10 , b 也可以看到是 10。
一樣可用在計數總共被創建幾次。
設定方式比較特別宣告後只能在類別外初始化
class OBJ{
    static int c;
};

int OBJ::c = 0;

類別內的靜態函式成員

這個更特別一些,可以把他解釋為
只為特定class工作,並且有特權的普通函式。
特權指的是可以存取私有成員,普通函式指的是沒有帶 this 指針。
可能會好奇沒有this指針怎麼存取,這就像 friend 函式一樣,你把物件指針導入就好了。
如果你想弄一個可以產生特定有效數據的類別,比如說 RGB
enmu RGB{R, G, B};
你想藉此避免使用者輸入無效數據
void fun(RGB img){

}
這麼一來就安全了,不過其實還有一種問題
某個人忘記初始化他..
RGB img;
手動建一個安全的函式群
class RGB{
public:
    static RGB R(){return RGB(0);}
    static RGB G(){return RGB(1);}
    static RGB B(){return RGB(2);}
private:
    RGB(int num): rgb(num){}
    unsigned rgb;
};
void fun(RGB img){}
好了,現在再也沒有人有能力建造出除了 0, 1, 2 以外的 RGB 了,因為RGB的建構子是私有的。現在只有 static 有特權可以存取私有的建構子。
fun(RGB::R());
你現在可以大坦的不檢查輸入的有效性了,因為他絕對安全又有效。


C 語言仿類別

根據以上的特性不知道你有沒有發現到,這就好像一個物件!
是的在C語言裡面把一份 .c 檔案視為一個物件,替變數或函式加上 static 就好像替他們宣告為 private 一樣。
雖然活運性沒有真實物件那麼好用,不過至少可以把變數與函式切的乾乾淨淨的,一塊一塊的,閱讀性與安全提升很多。
安全指的是多人合作時某人用你的函式,而妳不知道,事後你稍微調整個函式造成程式錯誤,你會很難找出來;以及某人 extend 你的變數,也是會發生一樣的事情。(雖然本來應該良好的溝通避免這種事情,不過從根本禁止還是方便有效些)。
不過別人跑來改掉妳的static就~XDD

沒有留言:

張貼留言