2010-05-04 167 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将不会显示,并且内存不会被删除,因为没有创建对象。