C++ SDL中错误处理和清理资源的良好实践?
在使用SDL时,我一直在处理错误(例如,在SDL初始化期间),每当函数中遇到错误时,我都返回C++ SDL中错误处理和清理资源的良好实践?,c++,error-handling,sdl,code-cleanup,C++,Error Handling,Sdl,Code Cleanup,在使用SDL时,我一直在处理错误(例如,在SDL初始化期间),每当函数中遇到错误时,我都返回false,否则返回true。然后通过调用main()函数末尾的close()函数执行清理,如下所示: int main(){ if(!init()){ // do some stuff } ... close(); return 0; } close()函数: void close(){ SDL_DestroyRenderer(g_R
false
,否则返回true
。然后通过调用main()
函数末尾的close()
函数执行清理,如下所示:
int main(){
if(!init()){
// do some stuff
}
...
close();
return 0;
}
close()
函数:
void close(){
SDL_DestroyRenderer(g_Renderer);
SDL_DestroyWindow(g_Window);
IMG_Quit();
SDL_Quit();
}
然而,我意识到这种清理方法意味着我不能真正抛出异常,因为不会调用close()
函数。
在做了一点阅读之后,我决定,除非出于性能相关的原因(我听说这很重要,尤其是在游戏开发中),否则我将尽量不抛出异常
此外,这意味着随着程序的增长,我需要添加更多的函数来清理close()
,这似乎不切实际,而且很容易忘记
因此,我的问题是:
unique_ptr
(或其他智能指针),并提供一个用于清理的deleter类atexit()
处理SDL\u Quit()
和IMG\u Quit()
SDL\u CreateWindow()
,我正试图避免这种情况。有什么帮助或建议吗
atexit()
处理SDL\u Quit()
和IMG\u Quit()
atexit
。其他替代方案可以让您更好地控制何时进行清理
unique_ptr
(或其他智能指针),并提供一个用于清理的deleter类
SDL\u Window*
,但是如果需要清理的不是指针怎么办?(例如,如果您想自动调用SDL\u Quit()
)
使用unique\u ptr
清理指针和其他清理其他东西的方法会毫无理由地在代码中引入不一致性,因此我会完全避免它(内存管理除外)
MyWindow(const MyWindow &) = delete;
MyWindow &operator=(const MyWindow &) = delete;
或者使类可移动且不可复制,以使其更易于使用
#include <exception>
#include <utility>
namespace Macro
{
template <typename T> class FinallyObject
{
T func;
public:
FinallyObject(T &&func) : func(std::move(func)) {}
FinallyObject(const FinallyObject &) = delete;
FinallyObject &operator=(const FinallyObject &) = delete;
~FinallyObject()
{
func();
}
};
}
#define FINALLY_impl_cat(a, b) FINALLY_impl_cat_(a, b)
#define FINALLY_impl_cat_(a, b) a##b
#define FINALLY(...) \
::Macro::FinallyObject FINALLY_impl_cat(_finally_object_,__LINE__) ([&]{ __VA_ARGS__ });
SDL\u退出
,SDL\u销毁窗口
等)
一般来说,在使用SDL时,我们应该在什么时候提出异常?除非需要,否则通常避免使用它们是否被视为良好做法 如果您正确地进行清理(使用析构函数和/或范围保护,而不是手动),异常将使这方面的工作变得更容易,而不是更困难
在你真的投球之前,它们不会对你的表现产生太大的影响,所以如果你只在很少的情况下投球,你应该是很好的。但是它们确实增加了二进制文件的大小。您的进程正在消失,何必麻烦呢?内核对象/句柄将作为进程终止的一部分关闭。还有什么?在创建包装类时,您认为为SDL和SDL_IMG初始化创建一个包装类是个好主意吗(包装SDL环境初始化感觉有点奇怪)?@PremsupapongVanitcharenthum,这取决于您。在我看来没有错。
int main(int, char **)
{
if (SDL_Init(...))
/*throw or exit with an error*/;
FINALLY( SDL_Quit(); )
SDL_Window *window = SDL_CreateWindow(...);
if (!window)
/*throw or exit with an error*/;
FINALLY( SDL_DestroyWindow(window); )
// Your code here.
}