C++ 如何在C++;?

C++ 如何在C++;?,c++,memory,free,static-members,C++,Memory,Free,Static Members,有人能解释一下如何释放静态成员变量的内存吗?据我所知,只有当类的所有实例都被销毁时,它才能被释放。我在这一点上有点无助 一些代码可以解释它: class ball { private: static SDL_Surface *ball_image; }; //FIXME: how to free static Variable? SDL_Surface* ball::ball_image = SDL_LoadBMP("ball.bmp"); 指针本身将一直存在,直到程序关闭。然

有人能解释一下如何释放静态成员变量的内存吗?据我所知,只有当类的所有实例都被销毁时,它才能被释放。我在这一点上有点无助

一些代码可以解释它:

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

指针本身将一直存在,直到程序关闭。然而,它所指的是公平的游戏。你可以随时释放它

如果您担心的是内存泄漏,那么我看到您有几个选择:

  • 就让它泄露出去吧。程序关闭时,将释放程序中的所有内存。但是,如果您需要的不仅仅是释放内存(比如您希望运行析构函数),那么这不是一个好主意

  • 有一个静态成员变量,用于跟踪已创建的类实例的数量。当内存达到0时释放内存,如果再次超过0,则重新分配内存

  • 有一个在程序关闭时运行的函数,它担心释放内存

  • 如果可以,让它不再是指针。如果不是指针,你就不用担心了

  • 使用或
    自动\u ptr
    。这样,当指针本身被破坏时,内存将得到保护


  • 就我个人而言,我会建议4如果你能,5如果你不能,但你有几个选择

    本例中的静态成员变量是指针。您无法释放它,但可以释放它指向的内容:

    SDL_FreeSurface(ball_image);
    
    然后,您可能希望将
    ball\u image
    设置为0,以记录您不再拥有图像的事实

    只有当类的所有实例都被销毁时,它才能被释放


    如果“类”的意思是
    ball
    ,则无论有多少
    ball
    实例,
    ball
    的静态成员都不会继续存在。在程序退出之前销毁静态成员的唯一方法是执行一些(依赖于实现的)操作,如卸载包含该类的dll。但是在这种情况下,静态成员只是一个指针,因此(1)销毁它只会销毁指针,而不是指针对象,(2)无论如何都不需要销毁指针,它不会占用大量资源。

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

    静态成员完全独立于其所属类的所有实例而存在。您可以在程序中的任意点删除指针。当然,这在语义上是有意义的,是另一个问题。

    < p>我同意Jonathan M Davis的回答,但是你可以考虑的另一个选择是将你的图片和其他资源从你的“域对象”中拉入资源管理器类,或者沿着这些线。 ResourceManager可以是静态的,也可以是基于实例的,并提供加载和删除应用程序其余部分所需资源的逻辑


    需要资源的类可以只持有指向全局资源管理器的引用或指针,并从管理器请求资源,而不是自己管理资源。

    从字面上看,您根本不需要指针。事实上,由于这是来自C库中的工厂函数,所以它实际上不是一个“一流”的C++指针。例如,您无法安全地
    删除它

    真正的问题(如果有)是在程序退出之前调用它的
    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;
    

    当程序初始化时,调用构造函数并读取文件。当程序退出时,调用析构函数并销毁对象。

    不需要删除静态成员变量。如果你在一个类中有一个,是因为你想在整个程序生命周期的任何时候使用它。一旦程序完成,操作系统将收回分配给它的总内存,包括任何未删除的内存空间


    当然,如果您坚持要删除它,您可以创建一个特殊的静态成员方法来执行它,并在程序中所需的点调用该方法。但是我不推荐给任何人,因为它破坏了静态成员变量的语义完整性,随着程序的增长,复杂性和引发问题的可能性也随之增加。

    使用动态分配内存的
    静态变量
    ,最好使用
    智能指针
    或手动清除内存的方法

    清除析构函数中静态变量的内存对于以下情况无效:
    As静态成员作为clas的
    成员存在,而不是作为类的每个对象中的
    实例存在。因此,如果有人使用
    ::
    访问静态变量并动态分配内存,那么
    析构函数将不会出现在图片中,内存也不会被删除,因为没有创建对象。

    删除了我的答案,这与您的答案类似,但没有那么彻底。我的想法是按照您在2中描述的那样做。但我认为有更好的办法。什么是智能指针?以前从没听说过。听起来像是垃圾收集。智能指针是一个对象,它持有指针,允许您像使用指针一样使用它,并在指针被破坏时释放内存(通常通过引用计数来查看指针是否还有任何引用)。它类似于垃圾收集,因为它为您管理内存,但它是一个单独的概念。我添加了一个到boost实现的链接。网上有很多关于它们的信息,包括维基百科。另外,如果你只是在这里搜索智能指针,你会得到许多与之相关的问题。另外,当你研究智能指针时,请注意
    auto_ptr
    h