C++ 当我从初始化函数返回时,为什么SDL窗口关闭?

C++ 当我从初始化函数返回时,为什么SDL窗口关闭?,c++,sdl,sdl-2,C++,Sdl,Sdl 2,我一直在开发一个简单的游戏引擎(我知道,我知道,我以前听过“编写游戏而不是引擎”,这只是为了理解概念)。我一直在使用SDL2,因为它与OpenGL配合得很好。然而,由于某些原因,一旦初始化功能完成,程序就会关闭 Screen.cpp: Screen::Screen(int width, int height, const std::string& title) { //Initialize SDL SDL_Init(SDL_INIT_EVERYT

我一直在开发一个简单的游戏引擎(我知道,我知道,我以前听过“编写游戏而不是引擎”,这只是为了理解概念)。我一直在使用SDL2,因为它与OpenGL配合得很好。然而,由于某些原因,一旦初始化功能完成,程序就会关闭

Screen.cpp:
Screen::Screen(int width, int height, const std::string& title)
    {

        //Initialize SDL
        SDL_Init(SDL_INIT_EVERYTHING);
        //Setting OpenGL Attributes
        SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
        SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
        SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
        SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
        SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

        //Create the Window
        m_window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
        l.writeToDebugLog("Created SDL_Window!");
        //Create OpenGL context from within SDL
        m_glContext = SDL_GL_CreateContext(m_window);
        l.writeToDebugLog("Created SDL GL Context!");

        //Initializing GLEW
        GLenum status = glewInit();
        l.writeToDebugLog( "Initializing GLEW");
        if (status != GLEW_OK)
        {
                l.writeToGLEWELog(" Glew Failed to Initialize!");
        }

        //setting the windowSurface to the m_window's surface
        windowSurface = SDL_GetWindowSurface(m_window);
        m_isClosed = false;
    }
这就是我创建screen对象并初始化所有SDL函数和OpenGL函数的地方

Engine.cpp:
        void Engine::initialize(){

        //Console Detecting platform
        c.initialize();
        //Printing Operating System to screen
        std::cout << "Loaded on : " << platformToString(c.os) << " OS " << std::endl;
        //Constructing a new Screen to be referenced too
        graphics::Screen temp(800,600,"ClimLib 0.0.05"); 

        //setting all the variables
        m_window = &temp;
        m_EntityManager = nullptr;
        m_isRunning = temp.isClosed();
        m_renderer = SDL_GetRenderer(m_window->getWindow());


    }
    void Engine::update(){
        do{
            //Check whether entities have been created and placed in the manager
            if (m_EntityManager != nullptr){
                for each(core::Entity *e in *m_EntityManager){
                    for each(core::Component *c in e->getComponentList()){
                        c->Update();
                    }
                }
            }


            //Update Logic Here
            m_window->Update();
            if (m_window->isClosed()){
                m_isRunning = false;
                return;
            }

            }while (isRunning());
        } 
这就是我目前的主要设置方式


编辑:我认为原因是我正在创建一个变量并将其存储为引用,当函数返回时,temp变量被丢弃?

您正在将屏幕创建为一个临时值,然后将该值的地址分配给一个指针,该指针的生存期实际上超过了它所指向的值的生存期,这很可能也是一个堆栈值。除了您的窗口死机的直接问题外,这将在以后使用时导致以下一个或两个问题:

  • 崩溃(非法内存访问)
  • 未定义的行为(在执行过程中读取位于该地址的堆栈上的随机值)
虽然现在可能不适用,但这确实是一个很好的方法,可以让你在任何事情上都感到头疼

您应该这样分配:

 m_window = new graphics::Screen(800,600,"ClimLib 0.0.05");
初始化它的方式意味着当函数在函数中声明和初始化时退出时,它将销毁自身。 使用new将保证它的存在,直到您删除它,因为除非您的代码删除它,否则它将位于堆的某个位置

只要确保在包含它的类的析构函数中调用delete m_window,以便在使用new创建窗口时正确清理窗口。您还可以将m_窗口声明为graphics::Screen,而不是graphics::Screen*,并只指定m_窗口,如下所示:

m_window = graphics::Screen(800,600,"ClimLib 0.0.05");

这样,您就不必担心以后自己删除它,因为删除包含的类时它会删除自己。

Engine::initialize
中,您可以
m_isRunning=temp.isClosed()
-现在假设窗口在此时打开,这将是
false
,并假设
Engine::isRunning())
返回
m_isRunning
您的
while(game.isRunning())
循环将立即终止。我更改了它,但它在游戏结束后立即关闭。initialize()-我在游戏结束后设置了一个断点。initialize()并在断点命中之前关闭了窗口。您是否尝试过调试,看看为什么你的循环会退出?如果不知道isRunning()的具体功能,很难从互联网的这一方面来判断:)我刚刚做了,我不明白为什么窗口从initialize函数返回后会删除,所有变量看起来都正确
temp
是一个局部变量,在initialize返回时会被销毁,这可能就是原因
m_window = graphics::Screen(800,600,"ClimLib 0.0.05");