Предотвратить преждевременное разрушение объекта - PullRequest
2 голосов
/ 12 марта 2012

Вот (соответствующий) код для моего pro::surface класса:

/** Wraps up SDL_Surface* **/
class surface
{
    SDL_Surface* _surf;
public:
    /** Constructor.
     ** @param surf an SDL_Surface pointer.
     **/
    surface(SDL_Surface*);

    /** Overloaded = operator. **/
    void operator = (SDL_Surface*);

    /** calls SDL_FreeSurface(). **/
    void free();

    /** destructor. Also free()s the internal SDL_Surface. **/
    virtual ~surface();
}

Теперь проблема в том, что в моей функции main объект разрушается сам (и, следовательно, вызывает деструктор, который опасно free() s Поверхность видео SDL!) До начала реального рендеринга.

int main(int argc, char** argv)
{
    ...
    // declared here
    pro::surface screen = SDL_SetVideoMode(320,240,16,SDL_HWSURFACE|SDL_DOUBLEBUF);

    // event-handling done here, but the Video Surface is already freed!
    while(!done) { ... }  // note that "screen" is not used in this loop.

    // hence, runtime error here. SDL_Quit() tries to free() the Video Surface again.
    SDL_Quit();
    return 0;
}

Итак, мой вопрос, есть ли способ остановить уничтожение самого экземпляра pro::surface до завершения программы? Хотя управление памятью работает вручную:

/* this works, since I control the destruction of the object */
pro::surface* screen = new pro::surface( SDL_SetVideoMode(..) ); 

/* it destroys itself only when **I** tell it to! Muhahaha! */
delete screen;

/* ^ but this solution uses pointer (ewww! I hate pointers) */

Но нет ли лучшего способа, не прибегая к указателям? Возможно, какой-то способ сказать стеку, чтобы он еще не удалил мой объект?

Ответы [ 2 ]

9 голосов
/ 12 марта 2012

Ты нарушил Правило Трех, сука.

pro::surface screen = SDL_SetVideoMode(320,240,16,SDL_HWSURFACE|SDL_DOUBLEBUF);

равно

pro::surface screen = pro::surface(SDL_SetVideoMode(320,240,16,SDL_HWSURFACE|SDL_DOUBLEBUF));

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

Редактировать: это также объясняет, почему ваша версия указателя работает нормально - потому что вы не вызываете копию.

2 голосов
/ 12 марта 2012

Оберните экран в специальную упаковку, которая соединяет SDL_SetVideoMode с SDL_Quit вместо SDL_FreeSurface.

pro::screen screen(320, 240, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
// ...

И исправьте свой экземпляр ctor, очевидно .

...