I thought about using something like the following so I don't have to remember to explicitly call destroyer functions at the end of methods:
#include <iostream>
#include <SDL2/SDL.h>
#include <memory>
int main()
{
SDL_Init(SDL_INIT_VIDEO);
std::unique_ptr<SDL_Window, decltype((SDL_DestroyWindow))>
win { SDL_CreateWindow("asdf", 100, 100, 640, 480, SDL_WINDOW_SHOWN),
SDL_DestroyWindow };
if (!win.get())
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateWindow Error: %s",
SDL_GetError());
return 1;
}
SDL_Quit();
}
I'm not sure if it's the best approach. I'm worried that this doesn't do what I want it to do even though it looks simple enough. Are there any subtle bugs to this approach?
Introduce a new scope and you should be OK:
int main()
{
SDL_Init(SDL_INIT_VIDEO);
{
std::unique_ptr<SDL_Window, decltype((SDL_DestroyWindow))>
win { SDL_CreateWindow("asdf", 100, 100, 640, 480, SDL_WINDOW_SHOWN),
SDL_DestroyWindow };
if (!win.get())
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_CreateWindow Error: %s",
SDL_GetError());
return 1;
}
} // win destroyed before SQL_Quit
SDL_Quit();
}
Use RAII even more:
struct SDL_RAII
{
SDL_RAII() { SDL_Init(SDL_INIT_VIDEO); }
~SDL_RAII() noexcept {
try {
SDL_Quit();
} catch (...) {
// Handle error
}
}
SDL_RAII(const SDL_RAII&) = delete;
SDL_RAII(SDL_RAII&&) = delete;
SDL_RAII& operator=(const SDL_RAII&) = delete;
SDL_RAII& operator=(SDL_RAII&&) = delete;
};
and be DRY by factorizing the deleter:
template <typename Object, void (*DeleterFun)(Object*)>
struct Deleter
{
void operator() (Object* obj) const noexcept
{
try {
DeleterFun(obj);
} catch (...) {
// Handle error
}
}
};
template <typename Object, void (*DeleterFun)(Object*)>
using UniquePtr = std::unique_ptr<Object, Deleter<Object, DeleterFun>>;
Then, some types for SDL:
using Unique_SDL_Window = UniquePtr<SDL_Window, SDL_DestroyWindow>;
using Unique_SDL_Surface = UniquePtr<SDL_Surface, SDL_FreeSurface>;
// ...
And finally:
int main()
{
SDL_RAII SDL_raii;
Unique_SDL_Window win{ SDL_CreateWindow("asdf", 100, 100, 640, 480, SDL_WINDOW_SHOWN)};
if (!win.get())
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"SDL_CreateWindow Error: %s",
SDL_GetError());
return 1;
}
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With