作者:龙飞
2.1:WasInit可以在Init前使用吗?
我们在介绍SDL_Init()的时候说过,这个函数是调用SDL其他函数之前必须首先调用的函数。但是有一个问题是,我们如何知道SDL_Init是否已经被调用过了呢?于是我们接着认识了SDL_WasInit(),这个函数可以返回Init的状态。如果WasInit用在了Init之前会出现什么问题,或者说,WasInit可以在Init前使用吗?
这个问题看起来似乎是逻辑混乱,但是事实上,有疑问向电脑问清楚是个好习惯。通过简单的试验,我们可以证实以下结论:SDL_WasInit()可以在SDL_Init()之前调用,返回值是0。这很合乎逻辑,没插旗子当然就没旗子,不是吗?
合乎正常的思维方式是:如果你准备穿西装,你最好应该弄清楚你自己身上是不是已经穿了一件西装(这个蹩脚的比喻主要是为了后面那个比喻做准备-_-!!)。所以,我们装载SDL之前,最好弄清楚SDL是不是已经装载了。结合前面的讨论和试验,我们写一个安全装载SDL的函数。
我们使用C++,当然知道<iostream>很好很强大,因为它已经包含了很多C的标准库。其中,atexit()是个用起来很方便的函数,它的形参是个函数指针,也就是个函数名,当然,这个被调用的函数需要满足返回值类型是viod,并且没有形参或者不能接受形参,即:void function();或者void function(viod);。atexit(function)在main()正常结束以及异常结束的时候,都会自动调用function()函数,所以,在我们不可预知程序是否会异常,或者不清楚程序什么时候结束的时候,需要做某些善后工作,atexit()是个很好的选择。
2.3:SDL的退出。
我们前面已经用到了SDL的退出函数,其原形是:
更多的时候,以及SDL官方文档里面,也推荐使用:atexit(SDL_Quit);
2.4:SDL_Quit(); 的容错性。
还是之前的那个问题的翻版,Quit可以在Init之前使用吗?答案依旧是肯定的。SDL_Quit();可以任意调用任意次,甚至不需要SDL_Init();的先行存在。
这是一种计算机对程序员的包容,但是这种包容并非总是好事情。一个逻辑上的正常思维应该是:你准备脱西装的时候最好弄明白自己身上到底是不是穿着西装。所以,我们在准备退出SDL的时候,最好也弄明白SDL是不是已经装载了。一个安全退出SDL的函数如下。
2.5:一段用于演示SDL安全装载与安全退出的程序。
2.1:WasInit可以在Init前使用吗?
我们在介绍SDL_Init()的时候说过,这个函数是调用SDL其他函数之前必须首先调用的函数。但是有一个问题是,我们如何知道SDL_Init是否已经被调用过了呢?于是我们接着认识了SDL_WasInit(),这个函数可以返回Init的状态。如果WasInit用在了Init之前会出现什么问题,或者说,WasInit可以在Init前使用吗?
这个问题看起来似乎是逻辑混乱,但是事实上,有疑问向电脑问清楚是个好习惯。通过简单的试验,我们可以证实以下结论:SDL_WasInit()可以在SDL_Init()之前调用,返回值是0。这很合乎逻辑,没插旗子当然就没旗子,不是吗?
合乎正常的思维方式是:如果你准备穿西装,你最好应该弄清楚你自己身上是不是已经穿了一件西装(这个蹩脚的比喻主要是为了后面那个比喻做准备-_-!!)。所以,我们装载SDL之前,最好弄清楚SDL是不是已经装载了。结合前面的讨论和试验,我们写一个安全装载SDL的函数。
void
beginSDL()
{
if ( SDL_WasInit(SDL_INIT_EVERYTHING) != 0 ) {
std::cout << " SDL is already running./n " ;
return ;
}
if ( SDL_Init(SDL_INIT_EVERYTHING) == - 1 ) {
throw " Unable to init SDL! " ;
}
std::cout << " SDL is running successfully./n " ;
return ;
}
{
if ( SDL_WasInit(SDL_INIT_EVERYTHING) != 0 ) {
std::cout << " SDL is already running./n " ;
return ;
}
if ( SDL_Init(SDL_INIT_EVERYTHING) == - 1 ) {
throw " Unable to init SDL! " ;
}
std::cout << " SDL is running successfully./n " ;
return ;
}
2.2:atexit();
我们使用C++,当然知道<iostream>很好很强大,因为它已经包含了很多C的标准库。其中,atexit()是个用起来很方便的函数,它的形参是个函数指针,也就是个函数名,当然,这个被调用的函数需要满足返回值类型是viod,并且没有形参或者不能接受形参,即:void function();或者void function(viod);。atexit(function)在main()正常结束以及异常结束的时候,都会自动调用function()函数,所以,在我们不可预知程序是否会异常,或者不清楚程序什么时候结束的时候,需要做某些善后工作,atexit()是个很好的选择。
2.3:SDL的退出。
我们前面已经用到了SDL的退出函数,其原形是:
void
SDL_Quit(
void
);
通常,我们在可以预测程序结束的时候直接使用语句:SDL_Quit();
更多的时候,以及SDL官方文档里面,也推荐使用:atexit(SDL_Quit);
2.4:SDL_Quit(); 的容错性。
还是之前的那个问题的翻版,Quit可以在Init之前使用吗?答案依旧是肯定的。SDL_Quit();可以任意调用任意次,甚至不需要SDL_Init();的先行存在。
这是一种计算机对程序员的包容,但是这种包容并非总是好事情。一个逻辑上的正常思维应该是:你准备脱西装的时候最好弄明白自己身上到底是不是穿着西装。所以,我们在准备退出SDL的时候,最好也弄明白SDL是不是已经装载了。一个安全退出SDL的函数如下。
void
endSDL()
{
if ( SDL_WasInit(SDL_INIT_EVERYTHING) == 0 ) {
std::cout << " SDL was NOT running!/n " ;
return ;
}
SDL_Quit();
std::cout << " SDL_Quit successfully./n " ;
return ;
}
{
if ( SDL_WasInit(SDL_INIT_EVERYTHING) == 0 ) {
std::cout << " SDL was NOT running!/n " ;
return ;
}
SDL_Quit();
std::cout << " SDL_Quit successfully./n " ;
return ;
}
2.5:一段用于演示SDL安全装载与安全退出的程序。
//
/
// File Name: test04.h
// SDL的安全装载与退出:头文件
// 联系我: znln426@163.com
// 再别流年的技术实验室
// http://www.cppblog.com/lf426/
// /
#include < iostream >
#include " SDL/SDL.h "
void beginSDL();
void endSDL();
// File Name: test04.h
// SDL的安全装载与退出:头文件
// 联系我: znln426@163.com
// 再别流年的技术实验室
// http://www.cppblog.com/lf426/
// /
#include < iostream >
#include " SDL/SDL.h "
void beginSDL();
void endSDL();
//
/
// File Name: test04.cpp
// SDL的安全装载与退出:实现文件
// 联系我: znln426@163.com
// 再别流年的技术实验室
// http://www.cppblog.com/lf426/
// /
#include " test04.h "
void beginSDL()
{
if ( SDL_WasInit(SDL_INIT_EVERYTHING) != 0 ) {
std::cout << " SDL is already running./n " ;
return ;
}
if ( SDL_Init(SDL_INIT_EVERYTHING) == - 1 ) {
throw " Unable to init SDL! " ;
}
std::cout << " SDL is running successfully./n " ;
return ;
}
void endSDL()
{
if ( SDL_WasInit(SDL_INIT_EVERYTHING) == 0 ) {
std::cout << " SDL was NOT running!/n " ;
return ;
}
SDL_Quit();
std::cout << " SDL_Quit successfully./n " ;
return ;
}
// File Name: test04.cpp
// SDL的安全装载与退出:实现文件
// 联系我: znln426@163.com
// 再别流年的技术实验室
// http://www.cppblog.com/lf426/
// /
#include " test04.h "
void beginSDL()
{
if ( SDL_WasInit(SDL_INIT_EVERYTHING) != 0 ) {
std::cout << " SDL is already running./n " ;
return ;
}
if ( SDL_Init(SDL_INIT_EVERYTHING) == - 1 ) {
throw " Unable to init SDL! " ;
}
std::cout << " SDL is running successfully./n " ;
return ;
}
void endSDL()
{
if ( SDL_WasInit(SDL_INIT_EVERYTHING) == 0 ) {
std::cout << " SDL was NOT running!/n " ;
return ;
}
SDL_Quit();
std::cout << " SDL_Quit successfully./n " ;
return ;
}
//
/
// File Name: main.cpp
// SDL的安全装载与退出:演示程序
// 联系我: znln426@163.com
// 再别流年的技术实验室
// http://www.cppblog.com/lf426/
// /
#include " test04.h "
int main( int argc, char * argv[])
{
try {
beginSDL();
}
catch ( const char * s ) {
std::cout << s << std::endl;
return - 1 ;
}
std::cout << SDL_WasInit(SDL_INIT_EVERYTHING) << std::endl;
atexit(endSDL);
return 0 ;
}
// File Name: main.cpp
// SDL的安全装载与退出:演示程序
// 联系我: znln426@163.com
// 再别流年的技术实验室
// http://www.cppblog.com/lf426/
// /
#include " test04.h "
int main( int argc, char * argv[])
{
try {
beginSDL();
}
catch ( const char * s ) {
std::cout << s << std::endl;
return - 1 ;
}
std::cout << SDL_WasInit(SDL_INIT_EVERYTHING) << std::endl;
atexit(endSDL);
return 0 ;
}