Как освободить статическую членскую переменную в C++?

Кто-либо может объяснить как свободной памяти статической членской Переменной? В моем понимании это может только быть освобождено, если все экземпляры класса уничтожаются. Я немного беспомощен в этой точке...

Некоторый Код для объяснения этого:

class ball
{
    private:
    static SDL_Surface *ball_image;
};
//FIXME: how to free static Variable?
SDL_Surface* ball::ball_image = SDL_LoadBMP("ball.bmp");
5
задан user299831 4 May 2010 в 23:15
поделиться

6 ответов

Судя по всему, вам вообще не нужен указатель. Фактически, поскольку это исходит от фабричной функции в библиотеке 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;

При инициализации программы вызывается конструктор и читается файл. Когда программа завершается, вызывается деструктор и объект уничтожается.

11
ответ дан 18 December 2019 в 05:49
поделиться

Статический член существует полностью независимо от всех экземпляров класса, членом которого он является. Вы можете удалить указатель в любой момент программы. Имеет ли это смысл семантически, это, конечно, другой вопрос.

1
ответ дан 18 December 2019 в 05:49
поделиться

Я согласен с ответом Джонатана М. Дэвиса, но другой вариант, который вы могли бы рассмотреть, - это вытащить ваши изображения и другие ресурсы из ваших «объектов домена» в класс ResourceManager или что-то в этом роде.

ResourceManager может быть статическим или основанным на экземпляре и обеспечивать логику для загрузки и удаления ресурсов, необходимых для остальной части нашего приложения.

Классы, которым требуются ресурсы, могут просто содержать ссылку или указатель на глобальный менеджер ресурсов и запрашивать ресурсы у менеджера, а не сами управлять ими.

1
ответ дан 18 December 2019 в 05:49
поделиться

Сам указатель будет существовать до тех пор, пока программа не выключится. Однако то, на что он указывает, - это честная игра. Вы можете освободить его в любое время.

Если вас беспокоит утечка памяти, то у вас есть несколько вариантов, которые я вижу:

  1. Просто позвольте ей утекать. Вся память из программы будет освобождена, когда она выключится. Однако, если вам нужно больше, чем просто освобождение памяти (например, вы хотите запустить деструктор), то это не очень хорошая идея.

  2. Иметь статическую переменную-член, которая отслеживает, сколько экземпляров класса было создано. Освободите память, когда она достигнет нуля, и перераспределите ее, если она снова станет больше 0.

  3. Создайте функцию, которая запускается при завершении работы программы, и пусть она позаботится об освобождении памяти.

  4. Если можете, сделайте так, чтобы это больше не был указатель. Если это не указатель, вам не нужно беспокоиться об этом.

  5. Используйте умный указатель или auto_ptr. Таким образом, когда сам указатель будет уничтожен, о памяти позаботятся.

Лично я бы посоветовал 4, если можете, и 5, если не можете, но у вас есть несколько вариантов.

12
ответ дан 18 December 2019 в 05:49
поделиться

Статическая переменная-член в данном случае является указателем. Вы не можете освободить ее, но вы можете освободить то, на что она указывает:

SDL_FreeSurface(ball_image);

Вы можете установить ball_image в 0, чтобы зафиксировать тот факт, что у вас больше нет изображения.

он может быть освобожден, только если все экземпляры класса уничтожены

Если под "классом" вы подразумеваете ball, то нет. Статические члены ball продолжают существовать независимо от того, сколько существует экземпляров ball. Единственный способ, при котором статический член может быть уничтожен до завершения программы, - это если вы сделаете какую-то (зависящую от реализации) вещь, например, выгрузите dll, содержащую класс. Но в этом случае статический член - это просто указатель, поэтому (1) при его уничтожении будет уничтожен только указатель, а не сам указатель, и (2) в любом случае нет необходимости уничтожать указатель, он не занимает значительных ресурсов.

3
ответ дан 18 December 2019 в 05:49
поделиться

Если вы должны иметь статический член, указывающий на память, выделенную из кучи, я бы сделал член умным указателем.

1
ответ дан 18 December 2019 в 05:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: