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

作者: Keitaro (動き出す時間...)   2016-09-13 00:50:30
開發平台(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這點我就不知道該怎麼寫測試程式了。
懇請各位先進指點以上迷津,感激不盡!
作者: Caesar08 (Caesar)   2016-09-13 01:05:00
你的global是指global object還是global scope?global與static object是不會放在stack上面的喔兩個都會隨著process結束而呼叫destructor如果是static pointer,那只有該pointer指到的在heap所以delete要自己想辦法處理
作者: Yshuan (倚絃)   2016-09-13 01:27:00
最簡單事做ref count
作者: CoNsTaR ((const *))   2016-09-13 03:36:00
class 就是可以被實例化的 namespace你在 class 裡宣告 static 和在同名的 namespace 裡宣告static 是一模一樣的在 namespace 裡宣告和在 global 宣告 static 就只差在 scope所以 static member 和 global 就只差在 scope
作者: steve1012 (steve)   2016-09-13 08:41:00
放class裡可以讓用class的人access到一些固定的資訊
作者: jaid (jaid)   2016-09-14 13:55:00
與其說是namespace不如說是為了更好的封裝性
作者: steve1012 (steve)   2016-09-14 14:45:00
其實namespace說得蠻好的吧 你要在class裡面放static就等於是在namespace 裡面做一樣
作者: jaid (jaid)   2016-09-14 22:36:00
因為這變數還可以設定成private隱藏起來
作者: kwpn (ITSST)   2016-09-15 12:11:00
若不是private、protected,那就是意義上的差別,放class裡代表變數"只"與此class相關,若不是就放global

Links booklink

Contact Us: admin [ a t ] ucptt.com