使用向量 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());
}
};
将 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());
}
};