使用向量 emplace 创建两个 sdl window 只会创建一个 window

Creating two sdl window using vector emplace creates only one window

将 sdl window 包装在 class 中并创建一个向量。然后放置两个 window objects 只会创建一个 window,尽管两个是预期的。

#include <SDL.h>
#include <vector>
class Window
{
    SDL_Window*     m_window;
    SDL_Renderer*   m_renderer;
    int m_windowID;
public:
    Window( int w, int h, Uint32 mode = SDL_WINDOW_SHOWN )
    {

        m_window = SDL_CreateWindow( "", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, mode );
        m_renderer = SDL_CreateRenderer( m_window , -1, SDL_RENDERER_PRESENTVSYNC );
        m_windowID = SDL_GetWindowID(m_window);
    }
    ~Window()
    {
        SDL_DestroyRenderer(m_renderer);
        SDL_DestroyWindow( m_window);
    }
    void render()
    {
        SDL_SetRenderDrawColor(m_renderer, 0xff, 0xff, 0xff, 0xff);
        SDL_RenderClear(m_renderer);
        SDL_RenderPresent(m_renderer);
    }
    void setTitle(const std::string& title)
    {
        SDL_SetWindowTitle(m_window, title.c_str());
    }
};
int main( int argc, char* argv[] )
{
    std::vector<Window> window;
    window.emplace_back(/*width*/600,/*height*/480);
    window.emplace_back(/*width*/600,/*height*/480);
    window[0].setTitle(/*title*/"window-1");
    window[1].setTitle(/*title*/"window-2");
    SDL_Event event;
    bool quit = false;
    while( !quit )
    {
        while( SDL_PollEvent( &event ) )
        {
            if( event.type == SDL_QUIT)
            {
                quit = true;
            }
        }
        for(auto& w: window)
        {
            w.render();
        }
    }
    return 0;
}

SDL_CreateWindow 被调用了两次,但只创建了一个 window,为什么?

更新:设置 window 的标题显示仅保留最后创建的 window。

您违反了 Three/Five 的规则。

推入第二个window后,向量被重新分配,第一个Window为"copied"。保留新副本,但调用旧副本的析构函数。新副本现在指向已销毁的 window。 (此外,window 在程序结束时第二次被销毁,这可能会导致未定义的行为)

如果您使用 std::unique_ptr 和适当的删除器,就不会发生这种情况。

#include <SDL2/SDL.h>
#include <vector>
#include <memory>

struct SDLWindowDestroyer
{
    void operator()(SDL_Window* w) const
    {
        SDL_DestroyWindow(w);
    }
};

struct SDLRendererDestroyer
{
    void operator()(SDL_Renderer* r) const
    {
        SDL_DestroyRenderer(r);
    }
};

class Window
{
    std::unique_ptr<SDL_Window, SDLWindowDestroyer>     m_window;
    std::unique_ptr<SDL_Renderer, SDLRendererDestroyer>   m_renderer;
    int m_windowID;
public:
    Window( int w, int h, const char* name, Uint32 mode = SDL_WINDOW_SHOWN ) :
        m_window(SDL_CreateWindow( name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, mode )),
        m_renderer(SDL_CreateRenderer( m_window.get() , -1, SDL_RENDERER_PRESENTVSYNC )),
        m_windowID(SDL_GetWindowID(m_window.get()))
    {

    }

    void render()
    {
        SDL_SetRenderDrawColor(m_renderer.get(), 0xff, 0xff, 0xff, 0xff);
        SDL_RenderClear(m_renderer.get());
        SDL_RenderPresent(m_renderer.get());
    }
};