防止对象过早破坏

时间:2012-03-12 18:50:28

标签: c++ oop memory-management destructor

以下是我的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() 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 个答案:

答案 0 :(得分:9)

你违反了三法则,婊子。

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));

现在双倍自由,因为你违反了三条规则。因此,为您的类提供一个正确的复制构造函数/赋值运算符,或者禁止它们并正确地构造它。

编辑:这也解释了为什么你的指针版本工作正常 - 因为你没有调用副本。

答案 1 :(得分:2)

将屏幕包裹在一个特殊的包装中,将SDL_SetVideoModeSDL_Quit配对,而不是SDL_FreeSurface

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

修复你的副本ctor,显然是