[問題] 請問static物件放在class裡面有何差異

看板C_and_CPP (C/C++)作者 (動き出す時間...)時間8年前 (2016/09/13 00:50), 8年前編輯推噓7(7014)
留言21則, 7人參與, 最新討論串1/1
開發平台(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

09/13 01:05, , 1F
你的global是指global object還是global scope?
09/13 01:05, 1F

09/13 01:08, , 2F
global與static object是不會放在stack上面的喔
09/13 01:08, 2F

09/13 01:09, , 3F
兩個都會隨著process結束而呼叫destructor
09/13 01:09, 3F

09/13 01:10, , 4F
如果是static pointer,那只有該pointer指到的在heap
09/13 01:10, 4F

09/13 01:10, , 5F
所以delete要自己想辦法處理
09/13 01:10, 5F

09/13 01:27, , 6F
最簡單事做ref count
09/13 01:27, 6F

09/13 03:36, , 7F
class 就是可以被實例化的 namespace
09/13 03:36, 7F

09/13 03:36, , 8F
你在 class 裡宣告 static 和在同名的 namespace 裡宣告
09/13 03:36, 8F

09/13 03:36, , 9F
static 是一模一樣的
09/13 03:36, 9F

09/13 03:37, , 10F
在 namespace 裡宣告和在 global 宣告 static 就只差在 s
09/13 03:37, 10F

09/13 03:37, , 11F
cope
09/13 03:37, 11F

09/13 03:38, , 12F
所以 static member 和 global 就只差在 scope
09/13 03:38, 12F

09/13 08:41, , 13F
放class裡可以讓用class的人access到一些固定的資訊
09/13 08:41, 13F

09/14 13:55, , 14F
與其說是namespace不如說是為了更好的封裝性
09/14 13:55, 14F

09/14 14:45, , 15F
其實namespace說得蠻好的吧 你要在class裡面放static
09/14 14:45, 15F

09/14 14:45, , 16F
就等於是在namespace 裡面做一樣
09/14 14:45, 16F

09/14 22:36, , 17F
因為這變數還可以設定成private隱藏起來
09/14 22:36, 17F

09/15 12:11, , 18F
若不是private、protected,那就是意義上的差別,放class裡
09/15 12:11, 18F

09/15 12:12, , 19F
代表變數"只"與此class相關,若不是就放global
09/15 12:12, 19F

10/19 04:27, , 20F
不建議使用喔
10/19 04:27, 20F

10/19 04:27, , 21F
文章代碼(AID): #1NrjpOu6 (C_and_CPP)
文章代碼(AID): #1NrjpOu6 (C_and_CPP)