看板 C_and_CPP 關於我們 聯絡資訊
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) VC2008 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) MFC 問題(Question): 請問global static物件,跟static member物件,有什麼差異? 補充說明(Supplement): 不好意思,小弟我想上來請教一下各位先進,關於static觀念上的問題。 我看書知道static本身在程式中是唯一的,即使我把static物件放在某個class裡面, 宣告N個class物件,這個static member還是只產生一個,所有物件共用。 那麼我有幾個關於static的疑問 1. 請問static object放在class裡面跟不放class裡面有什麼差別? 既然所有宣告出來的class物件都共用static member object, 那跟global有什麼差異呢?只為了namespace做區隔嗎? 2. 關於static物件的free memory問題 我會想到用static物件是因為工作上有一個地方要重構,原本一個物件要改生成N個。 其中關於繪圖的部分,MFC內建的一些像CPen/CBrush之類的物件都是一樣的。 因此我才想說用static來寫。 但是這樣一來就衍生了對於static的問題。 由於CPen/CBrush這些class物件,生成後必須要做DeleteObject()這個動作。 原本我是把DeleteObject放在class的解構式裡面。 但我現在已經把CPen宣告成static,所有物件共用, 我不能讓DeleteObject()去執行N次。 因此我改寫程式碼為 // header class CTestDlg { static CPen m_Pen; } // cpp CPen CTestDlg::m_Pen; CTestDlg::~CTestDlg() { if (m_Pen.GetSafeHandle()) <-加上這一行 m_Pen.DeleteObject(); } 後來我進入DeleteObject()裡面看到,微軟其實有做防護, 第二次以後做DeleteObject()會直接return false,所以我不加這一行也沒差。 那問題來了... a. 是否寫成static member物件,如果需要做free memory,就一定要加這個判斷式? b. 如果static member物件本身不需要free memory,是否不需要對它做任何處理, 等到stack memory做free的時候自然會去call static member物件的解構式? 我先實驗了b這一點,測試程式如下 // header class CTestA { } class CTestB { static CTestA m_A; } // cpp CTestA CTestB::m_A; CTestA::~CTestA() { const char str[] = "~A()"; ::OutputDebugStringA(str); } CTestB::~CTestB() { const char str[] = "~B()"; ::OutputDebugStringA(str); } int _tmain(int argc, _TCHAR* argv[]) { CTestB Obj_B; return 0; } 然後我就看到印出訊息 "~B()" "~A()" 在"~B()"印出訊息時看出程式在離開main的時候free local variable, 但是印出"~A()"的時候就看不出來stack了。 所以我猜想我對於b的猜測應該是對的? a這點我就不知道該怎麼寫測試程式了。 懇請各位先進指點以上迷津,感激不盡! -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 111.251.209.113 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1473699032.A.E06.html ※ 編輯: Keitaro (111.251.209.113), 09/13/2016 00:52:04 ※ 編輯: Keitaro (111.251.209.113), 09/13/2016 00:53:52
Caesar08: 你的global是指global object還是global scope? 09/13 01:05
Caesar08: global與static object是不會放在stack上面的喔 09/13 01:08
Caesar08: 兩個都會隨著process結束而呼叫destructor 09/13 01:09
Caesar08: 如果是static pointer,那只有該pointer指到的在heap 09/13 01:10
Caesar08: 所以delete要自己想辦法處理 09/13 01:10
Yshuan: 最簡單事做ref count 09/13 01:27
CoNsTaR: class 就是可以被實例化的 namespace 09/13 03:36
CoNsTaR: 你在 class 裡宣告 static 和在同名的 namespace 裡宣告 09/13 03:36
CoNsTaR: static 是一模一樣的 09/13 03:36
CoNsTaR: 在 namespace 裡宣告和在 global 宣告 static 就只差在 s 09/13 03:37
CoNsTaR: cope 09/13 03:37
CoNsTaR: 所以 static member 和 global 就只差在 scope 09/13 03:38
steve1012: 放class裡可以讓用class的人access到一些固定的資訊 09/13 08:41
jaid: 與其說是namespace不如說是為了更好的封裝性 09/14 13:55
steve1012: 其實namespace說得蠻好的吧 你要在class裡面放static 09/14 14:45
steve1012: 就等於是在namespace 裡面做一樣 09/14 14:45
jaid: 因為這變數還可以設定成private隱藏起來 09/14 22:36
kwpn: 若不是private、protected,那就是意義上的差別,放class裡 09/15 12:11
kwpn: 代表變數"只"與此class相關,若不是就放global 09/15 12:12
godspeedlee: 不建議使用喔 10/19 04:27
godspeedlee: http://tinyurl.com/hcqfc9x 10/19 04:27