简体   繁体   English

如何在C ++中释放静态成员变量?

[英]How to free static member variable in C++?

Can anybody explain how to free memory of a static member Variable? 任何人都可以解释如何释放静态成员变量的内存吗? In my understanding it can only be freed if all the instances of the class are destroyed. 根据我的理解,只有在类的所有实例都被销毁时才能释放它。 I am a little bit helpless at this point... 此时我有点无助......

Some Code to explain it: 一些代码来解释它:

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

The pointer itself will be around until the program shuts down. 指针本身将一直存在,直到程序关闭。 However, what it points to is fair game. 然而,它指的是公平游戏。 You can free that at any time. 您可以随时免费使用。

If what you're worried about is memory leaks, then you have a few options that I see: 如果您担心的是内存泄漏,那么您可以看到以下几个选项:

  1. Just let it leak. 只是让它泄漏。 All the memory from the program will be released when it shuts down. 程序中的所有内存将在关闭时释放。 However, if you need more than just the memory being freed (like you want a destructor to run), then that's not such a good idea. 但是,如果您需要的不仅仅是释放的内存(就像您想要运行析构函数一样),那么这不是一个好主意。

  2. Have a static member variable which keeps track of how many instances of the class have been created. 有一个静态成员变量,用于跟踪已创建的类的实例数。 Free the memory when it reaches zero and reallocate it if it goes above 0 again. 当内存达到零时释放内存,如果内存再次高于0则重新分配内存。

  3. Have a function of some kind which runs when the program is shutting down and have it worry about freeing the memory. 有一种在程序关闭时运行的某种功能,并且担心释放内存。

  4. If you can, make it so that it's not a pointer anymore. 如果可以,那就让它不再是指针了。 If it's not a pointer, you don't have to worry about it. 如果它不是指针,你不必担心它。

  5. Use a smart pointer or auto_ptr . 使用智能指针auto_ptr That way, when the pointer itself is destroyed, the memory will be taken care of. 这样,当指针本身被破坏时,内存将被处理。

Personally, I'd advise 4 if you can and 5 if you can't, but you have several options. 就个人而言,如果可以,我会建议4,如果你不能,我会建议5,但你有几种选择。

From the sound of it, you don't really want a pointer at all. 从它的声音,你真的不想要一个指针。 In fact, since this is coming from a factory function in a C library, it isn't really a "first-class" C++ pointer. 实际上,由于这是来自C库中的工厂函数,因此它实际上并不是“一流的”C ++指针。 For example, you can't safely delete it. 例如,您无法安全地delete它。

The real problem (if there is one) is to call SDL_FreeSurface on it before the program exits. 真正的问题(如果有的话)是在程序退出之前调用SDL_FreeSurface

This requires a simple wrapper class. 这需要一个简单的包装类。

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;

When the program initializes, the constructor is called and the file is read. 程序初始化时,调用构造函数并读取文件。 When the program exits, the destructor is called and the object is destroyed. 程序退出时,将调用析构函数并销毁对象。

The static member variable in this case is a pointer. 在这种情况下,静态成员变量是一个指针。 You can't free it, but you can free what it points to: 你不能释放它,但你可以释放它指向的东西:

SDL_FreeSurface(ball_image);

You might then want to set ball_image to 0, to record the fact that you no longer have an image. 然后,您可能希望将ball_image设置为0,以记录您不再拥有图像的事实。

it can only be freed if all the instances of the class are destroyed 只有在类的所有实例都被销毁时才能释放它

If by "the class" you mean ball , then no. 如果“上课”是指ball ,那么没有。 Static members of ball continue to exist regardless of how many instances of ball there are. 静态成员ball继续无论怎样的许多情况下,存在ball有。 The only way a static member might be destroyed before program exit is if you do some (implementation-dependent) thing like unloading the dll which contains the class. 在程序退出之前,静态成员可能被销毁的唯一方法是,如果你做一些(依赖于实现)的事情,比如卸载包含类的dll。 But in this case the static member is just a pointer, so (1) destroying it will just destroy the pointer, not the pointee, and (2) there is no need to destroy a pointer anyway, it doesn't occupy significant resources. 但在这种情况下,静态成员只是一个指针,因此(1)销毁它只会破坏指针,而不是指针对象,并且(2)无论如何都不需要销毁指针,它不会占用大量资源。

如果必须将静态成员指向堆分配的内存,我会使成员成为智能指针。

A static member exists completely independently of all instances of the class it is a member of. 静态成员完全独立于它所属的类的所有实例。 You can delete the pointer at any point in the program. 您可以在程序中的任何位置删除指针。 Whether this makes sense semantically, is another issue, of course. 当然,这在语义上是否有意义是另一个问题。

I agree with Jonathan M Davis' answer, but another option you could consider is pulling your images and other resources out of your "domain objects" and into a ResourceManager class, or something along those lines. 我同意Jonathan M Davis的回答,但您可以考虑的另一个选择是将您的图像和其他资源从“域对象”中提取出来并转移到ResourceManager类中,或者沿着这些方向。

The ResourceManager could either be static, or instance-based, and would provide the logic to load and delete resources, needed by the rest of our application. ResourceManager可以是静态的,也可以是基于实例的,并且可以提供加载和删除资源的逻辑,这是我们应用程序的其余部分所需要的。

Classes needing resources could just hold a reference or a pointer to the global resource manager, and request resources from the manager, rather than managing them themselves. 需要资源的类可以只保存一个引用或指向全局资源管理器的指针,并从管理器请求资源,而不是自己管理它们。

Static member variables don't need to be deleted. 不需要删除静态成员变量。 If you have one within a class, is because you want to use it at any time during the entire life of the programme. 如果你在课堂上有一个,那是因为你想在整个课程期间的任何时候使用它。 Once the programme finishes, the Operating System claims back the total memory assigned to it, including any undeleted memory space. 程序完成后,操作系统会声明分配给它的总内存,包括任何未删除的内存空间。

Of course, if you insist in deleting it, you can create a special static member method for doing it and invoke the method at a desired point in the programme. 当然,如果您坚持删除它,您可以创建一个特殊的静态成员方法来执行它,并在程序中的所需位置调用该方法。 But I woudn't recommend it to anyone, because it violates the semantic integrity of the static member variables, increasing so the complexity and the likelihood for causing troubles as the programme grows. 但我不推荐它给任何人,因为它违反了静态成员变量的语义完整性,增加了复杂性以及随着程序的增长而引起麻烦的可能性。

Working with a static variable where the memory is dynamically allocated, it is better to go with smart_pointer or a method where memory is cleared manually. 使用动态分配内存的static variable ,最好使用smart_pointer或手动清除内存的方法。

Clearing the memory of static varibles in the destructor will not work for the below case: As static members exist as members of the clas s rather than as an instance in each object of the class . 清除destructor中静态变量的内存不适用于以下情况:由于静态成员作为members of the clasmembers of the clas而不是作为instance in each object of the class So if someone access a static variable using :: and dynamically allocate memory, the destructor will not come in picture and the memory will not get deleted, as there is no object created. 因此,如果某人使用::并动态分配内存来访问静态变量,则destructor将不会出现,并且内存不会被删除,因为没有创建对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM