2010-05-04 168 views
5

任何人都可以解釋如何釋放靜態成員變量的內存?根據我的理解,只有在類的所有實例都被銷燬的情況下才能釋放它。我有點有點無奈在這一點上...如何在C++中釋放靜態成員變量?

一些代碼來解釋它:

class ball 
{ 
    private: 
    static SDL_Surface *ball_image; 
}; 
//FIXME: how to free static Variable? 
SDL_Surface* ball::ball_image = SDL_LoadBMP("ball.bmp"); 

回答

11

從它的聲音來看,你根本不需要指針。實際上,因爲這是來自C庫中的工廠函數,所以它不是真正的「一流」C++指針。例如,你不能安全delete它。

真正的問題(如果有的話)是在程序退出之前調用SDL_FreeSurface

這需要一個簡單的包裝類。

struct smart_sdl_surface { 
    SDL_Surface *handle; 

    explicit smart_sdl_surface(char const *name) 
     : handle(SDL_LoadBMP(name)) {} 
    ~smart_sdl_surface() 
     { SDL_FreeSurface(handle); } 
}; 

class ball 
{ 
    private: 
    static smart_sdl_surface ball_image_wrapper; 
    static SDL_Surface *& ball_image; // reference to the ptr inside wrapper 
}; 
smart_sdl_surface ball::ball_image_wrapper("ball.bmp"); 
SDL_Surface *&ball::ball_image = ball::ball_image_wrapper.handle; 

當程序初始化時,調用構造函數並讀取文件。當程序退出時,析構函數被調用並且對象被銷燬。

12

指針本身將圍繞直到程序關閉。然而,它指的是公平的遊戲。你可以在任何時候釋放它。

如果你是擔心的是內存泄漏,那麼你有,我看到幾個選項:

  1. 就讓它漏氣。程序中的所有內存將在關閉時釋放。然而,如果你需要的不僅僅是內存被釋放(就像你想要析構函數一樣),那麼這不是一個好主意。

  2. 有一個靜態成員變量,用於跟蹤創建了多少個類的實例。當內存達到零時釋放內存,如果再次高於0則重新分配內存。

  3. 有程序關閉時運行某種類型的函數,並且擔心釋放內存。

  4. 如果可以,使它不再是指針。如果它不是指針,則不必擔心。

  5. 使用smart pointerauto_ptr。這樣,當指針本身被銷燬時,內存將被照顧。

就個人而言,我建議4如果你能和5,如果你不能,但你有幾種選擇。

+0

刪除了我的答案,與您的答案類似,但沒有詳盡。 – Nate 2010-05-04 23:27:02

+0

我的想法是像你在2中描述的那樣做,但我認爲可能有更好的方法。 什麼是智能指針?從來沒有聽說過。聽起來像垃圾回收.. – user299831 2010-05-04 23:34:53

+0

智能指針是一個持有指針的對象,允許您像指針一樣使用它,並在指針被銷燬時釋放該指針的內存(通常通過引用計數來查看是否存在是指針留下的任何引用)。它與垃圾收集類似,它爲您管理內存,但它是一個單獨的概念。我添加了一個鏈接到boost實現。網上有大量的信息 - 包括維基百科。另外,如果你只是在SO搜索智能指針,你會得到一些與它們相關的問題。 – 2010-05-05 00:04:53

3

這種情況下的靜態成員變量是一個指針。你不能釋放它,但你可以釋放它所指向:

SDL_FreeSurface(ball_image); 

你可能再要設置ball_image爲0,記錄的事實,你不再有一個形象。

如果類的所有實例如果破壞

它只能被釋放「之類的」你的意思是ball,則沒有。無論有多少個ball實例,ball的靜態成員都會繼續存在。在程序退出前,一個靜態成員可能會被銷燬的唯一方法是,如果你執行一些(實現相關的)事情,比如卸載包含該類的dll。但在這種情況下,靜態成員只是一個指針,所以(1)銷燬它只會破壞指針,而不是指針,(2)無論如何不需要銷燬指針,它不會佔用大量資源。

1

如果你必須有靜態成員指向堆分配內存,我會讓一個成員成爲一個智能指針。

1

一個靜態成員完全獨立於它所屬類的所有實例。您可以在程序中的任何位置刪除指針。當然,這在語義上是否合理是另一個問題。

1

我同意Jonathan M Davis的回答,但您可以考慮的另一個選擇是將圖像和其他資源從您的「域對象」和ResourceManager類中拉出來,或者沿着這些線拉出。

ResourceManager可以是靜態的,也可以是基於實例的,並且可以提供加載和刪除資源的邏輯,這是我們其他應用程序所需要的。

需要資源的類只能持有一個引用或指向全局資源管理器的指針,並向管理器請求資源,而不是自己管理它們。

0

靜態成員變量不需要刪除。如果你在課堂上有一個,那是因爲你想在課程的整個生命週期中隨時使用它。一旦程序結束,操作系統會聲明分配給它的全部內存,包括任何未刪除的內存空間。

當然,如果您堅持刪除它,您可以創建一個特殊的靜態成員方法來執行此操作,並在程序中的所需位置調用該方法。但是我不會向任何人推薦它,因爲它違反了靜態成員變量的語義完整性,從而增加了隨着程序增長而導致麻煩的複雜性和可能性。

0

使用內存動態分配的static variable,最好使用smart_pointer或者手動清除內存的方法。

清除靜態變量下的存儲器中destructor不會爲以下情況下工作: 作爲靜態成員members of the clas做得相當不是作爲instance in each object of the class存在。因此,如果某人使用::訪問靜態變量並動態分配內存,則destructor將不會顯示,並且內存不會被刪除,因爲沒有創建對象。