我用SDL2进行编程,但我无法理解以下原因。这有效:
SDL_Window *window;
SDL_Surface *screen_surface;
SDL_Surface *picture;
auto initWindow(void)
{…}
auto loadMedia(void)
{…}
auto close(void)
{…}
int main(void)
{
initWindow();
loadMedia();
…
close();
}
然而,这不是:
auto initWindow(SDL_Window *window, SDL_Surface *screen_surface)
{…}
auto loadMedia(SDL_Surface *picture, std::string resource)
{…}
auto close(SDL_Window *window, SDL_Surface *picture)
{…}
int main(void)
{
SDL_Window *window;
SDL_Surface *screen_surface;
SDL_Surface *picture;
initWindow(window, screen_surface);
loadMedia(picture, "resource_file.bmp");
…
close(window, picture);
}
唯一的区别是我从文件范围中取出window
,screen_surface
和picture
并将其放入块范围(即主函数),而不是在这些函数中引用全局变量,我使用参数。
但是,当我尝试运行它时,它会显示一个白色屏幕,但不会显示任何错误。我不明白这里出了什么问题。
答案 0 :(得分:3)
免责声明:我从未做过任何SDL编程,所以这只是基于常识和我可以从评论中读到的答案。
假设您的initWindow
函数为window
变量设置了一些值。当在全局范围内声明该变量时,使用此变量的所有其他函数也会看到对它的修改。
当您将该变量更改为函数参数时,这会发生巨大变化。根据您提供的代码:
auto initWindow(SDL_Window *window, SDL_Surface *screen_surface)
{
window = SDL_GetWindow(); /* or something */
}
int main(void)
{
SDL_Window *window;
SDL_Surface *screen_surface;
initWindow(window, screen_surface);
/* some other code that uses 'window' */
}
仅 window
中的initWindow
实际上设置为SDL_GetWindow
的值。 window
内的main
变量未更改:main
中需要使用它的所有其他函数将访问未初始化的变量,这是未定义的行为。您也有资源泄漏,因为您现在永远无法释放SDL_GetWindow
的内容。 initWindow
实际上会收到window
的副本,这个window
与main
中的initWindow
完全无关。
了解您如何使用C ++,解决此问题的最佳方法是让window
接受对auto initWindow(SDL_Window *&window, SDL_Surface *&screen_surface)
{
window = SDL_GetWindow(); /* or something */
}
int main(void)
{
SDL_Window *window;
SDL_Surface *screen_surface;
initWindow(window, screen_surface);
/* some other code that uses 'window' */
}
变量的引用,如下所示:
window
现在,main
内的initWindow
变量将使用window
对其执行的操作进行更新,以后main
中使用SDL_GetWindow
的代码将会访问通过std::unique_ptr
获取的资源。
但是,C ++允许您通过使用构造函数和析构函数以更有效的方式管理资源,这一概念称为RAII(资源获取是初始化)。寻找围绕SDL对象的C ++包装器,这将使您的生活更轻松,如果您不这样做,花一些时间编写自己的,或使它们与std::shared_ptr
(或SELECT u.email, u.password FROM utenti u WHERE u.email = ?
如果您一起工作知道你需要它)。你以后会感谢自己。