2011年6月20日 星期一

"STATIC" - C/C++ Programming

"static" : a programming tag that confuses and troubles many people, and so am I of course.

The following content and information is referenced from others' blog:

  • Static Variable (靜態變數):
  • static 放在 variable 前時,代表這個 variable 的存活時間和整個程式一樣長。也就是 life time 跟整個 Process 一樣長,而 scope 則維持不變。
    Example:
    執行結果 x=5 y=1 TestFunction 會對 x , y 配置記憶體空間並進行 initial,當 TestFunction 結束的時候,會將 y 的記憶體歸還,下次呼叫時再重新配置一次;而x被宣告成static,所以x的記憶體不會歸還,延用著上次的值。
    碎碎念1:似乎可以看成被宣告成 static 的變數,其實就是 global 的了,只是因為 x 是宣告在 TestFunction 裡,所以只能在 TestFunction 裡用。
    碎碎念2:如果把 x 宣告在外面當成 global,那 int x; 和 static int x; 是一樣的。
    碎碎念3:在 TestFunction 裡,static int x=0; 的初始化只會做一次。如果寫成 static int x; x=0; 那結果就會跟 y 一樣。

  • Static Member Variable (靜態成員變數):
  • 在 class 裡把 member variable 宣告成 static,代表他是「與 class 相關連」,而不是「與物件相關連」。他獨立配置記憶體,獨立於 class 的任何物件而存在,這個 class 產生的所有物件共用使同一個 static member variable,甚至不需要有物件也能夠被使用。
    因為 static member variable 不屬於任何物件,所以必須定義在外面。與一般成員變數不同,static member variable 並不是經由 constructor 初始化,而是在定義時被初始化。
    碎碎念1:可以看做是一個存在於某個 class 的 global variable。

  • Static Member Function (靜態成員函式):
  • 如果static member variable是private的
    如果 static member variable 是 private 的,那就沒有辦法直接取了,那該怎麼辦呢?寫一個 Get 的 member function?
    這樣不是很奇怪嗎?因為 m_nNum 在不是 private 的時候,可以不用產生物件就可以存取,但是用 Get member function 卻要產生一個物件。所以這樣的方法並不好,因此,就要把 Get member function 也宣告成static的。
    static member function 也跟 static member variable 一樣,獨立於物件存在。可以在沒有物件產生的狀況下被使用,所以他不能使用 this,也不能存取 class 裡的一般成員變數,當然也不能使用一般成員函式了。
    也就是說,static member function 只能存取 static member variable。
    那如果真的想用呢?就要用以下的方法:
    執行結果:
    A::m_nNum=0
    建立物件a1
    A::m_nNum=0
    a1.m_nNum=0
    a1.GetNum2()=10
    a1.StaticGetNum3()=20

    建立物件a2
    A::m_nNum=0
    a2.m_nNum=0
    a2.GetNum2()=10
    a2.StaticGetNum3()=100  // 把a2的m_nNum3從20設成100
    a1.StaticGetNum3()=100  // Question!?
    a1.GetNum3()=20
    值得注意的是 a1.StaticGetNum3()=100,a1 的 m_nNum3 是 100 嗎?a1 的 m_nNum3 明明就是20,而 a2 的 m_nNum3 才是100,那為什麼這裡會錯了呢?
    主要的問題是來自於 m_pThis,我們為了讓 static member function 可以存取一般成員函式和成員變數,所以使用 m_pThis 指向自己來取得一般成員函式和成員變數,而且為了讓 static member function 可以使用 m_pThis 指標,還把 m_pThis 指標宣告成 static 的。
    宣告成 static 就表示他是所有物件共用的,所以當產生 a1 物件時,m_pThis 是指向 a1 物件的,而產生 a2 物件時 m_pThis 就改指向 a2 物件了,所以就算透過 a1 物件取得 m_pThis,也都會取得 a2 物件了。
    碎碎念1:要避免這問題,只能想辦法確保 A 類別只會產生1個物件? singleton ?沒有別的辦法嗎? 有的!就是把物件自己當成參數傳進 static member function 裡。
referenced from - C++的static @ 伊卡洛斯之翼

0 意見: