在MinGW上,Singleton类的析构函数无法清理(SDL_Quit)。

问题描述 投票:0回答:2

我的SDL程序在MinGW上运行时不返回(如下图)。如果我移动 SDL_Quit 在单人类的dtor之外到main的结尾,它不再有问题。所以我认为是构造销毁顺序的问题。但是没有其他需要破坏的东西。我到底做错了什么?

#include <SDL.h>

class ExceptionType {};

class SDL_DisplayType
{
public:
    static SDL_DisplayType& Instance ()
    {
        static SDL_DisplayType myInstance;
        return myInstance;
    }   

    SDL_Window*   sdlWindow_;
    SDL_Renderer* sdlRenderer_;

private:
    SDL_DisplayType  ();    
    ~SDL_DisplayType (); 
};

SDL_DisplayType::SDL_DisplayType() 
{
    if (SDL_Init (SDL_INIT_EVERYTHING) < 0) throw ExceptionType ();

    sdlWindow_ = SDL_CreateWindow ("",SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,640, 480, 0);
    if (! sdlWindow_) throw ExceptionType ();

    sdlRenderer_ = SDL_CreateRenderer (sdlWindow_, -1, 0);
    if (! sdlRenderer_) throw ExceptionType ();
}

SDL_DisplayType::~SDL_DisplayType ()
{
    SDL_Quit (); //<-- Move this to end of main and problem goes away
}

int main (int argc, char** argv)
{
    //draw something, just so I can call SDL_DisplayType::Instance
    SDL_SetRenderDrawColor(SDL_DisplayType::Instance ().sdlRenderer_, 255, 255, 255, 255);
    SDL_RenderDrawLine    (SDL_DisplayType::Instance ().sdlRenderer_, 0, 0, 100, 100);
    SDL_RenderPresent     (SDL_DisplayType::Instance ().sdlRenderer_);

    while (true) //wait for key hit
    {
        SDL_Event sdlEvent; 
        if (SDL_WaitEvent (&sdlEvent) == 0) throw ExceptionType ();
        if (sdlEvent.type == SDL_KEYDOWN) break ;
    }

    return 0;
}

Makefile,如果有用的话。

INCLUDE_FLAGS   =   -I..\..\SDL2-MinGW\SDL2\i686-w64-mingw32\include\SDL2       \
                    -I..\..\SDL2-MinGW\SDL2_image\i686-w64-mingw32\include\SDL2 \
                    -I..\..\SDL2-MinGW\SDL2_mixer\i686-w64-mingw32\include\SDL2 \
                    -I..\..\SDL2-MinGW\SDL2_ttf\i686-w64-mingw32\include\SDL2   

LIBRARY_PATH    =   -L..\..\SDL2-MinGW\SDL2\i686-w64-mingw32\lib        \
                    -L..\..\SDL2-MinGW\SDL2_image\i686-w64-mingw32\lib  \
                    -L..\..\SDL2-MinGW\SDL2_mixer\i686-w64-mingw32\lib  \
                    -L..\..\SDL2-MinGW\SDL2_ttf\i686-w64-mingw32\lib                    

a.out:  main.o 
    g++ -g $(LIBRARY_PATH) main.o -lmingw32 -lSDL2main -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -L. 

main.o: main.cpp
    g++ -g -c  $(INCLUDE_FLAGS) main.cpp
c++ singleton mingw sdl-2
2个回答
0
投票

在C++中,对静态数据的销毁顺序没有约束(当编译在分离的文件中时)。那么,千万不要在一个单子的destructor中使用(直接或不使用)静态数据,因为你无法知道数据是否还存在。

在你的情况下,你可能尝试调用一些已经被销毁的SDL东西。


0
投票

但是没有其他需要被销毁的东西。我到底做错了什么?

那么,通过查看你的 SDL_DisplayType's 破坏者:

SDL_DisplayType::~SDL_DisplayType ()
{
    SDL_Quit ();
}

你可以意识到,这两个 SDL_DisplayType的数据成员 - sdlWindow_sdlRenderer_ - 创立于 构造者但它们在这里并没有被销毁,而是在相应的destructor中。

请考虑在相应的分解器中调用 SDL_DestroyRenderer()SDL_DestroyWindow() - 按照这个顺序 SDL_DisplayType的析构器,然后再调用 SDL_Quit()即:

SDL_DisplayType::~SDL_DisplayType () {
    SDL_DestroyRenderer(sdlRenderer_);
    SDL_DestroyWindow(sdlWindow_);
    SDL_Quit ();
}
© www.soinside.com 2019 - 2024. All rights reserved.