不能在块范围内使用 SDL2 变量
Can't use SDL2 variables in Block scope
我正在用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
从 文件范围 中取出并放入 块范围(即主函数),而不是在这些函数中引用全局变量,我使用参数。
但是,当我尝试 运行 时,它会显示白屏,但不会显示任何错误。我不明白这里出了什么问题。
免责声明:我从来没有做过任何 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' */
}
只有initWindow
中的window
实际设置为SDL_GetWindow
的值。 main
中的 window
变量没有改变:所有其他需要在 main
中使用它的函数将访问一个未初始化的变量,这是未定义的行为。你也有资源泄漏,因为你现在永远无法释放你从 SDL_GetWindow
得到的东西。 initWindow
实际上收到了 window
的 副本 ,与 main
中的 window
完全无关。
看看您是如何使用 C++ 的,最好的解决方法是让 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' */
}
现在,main
中的 window
变量将更新为 initWindow
对其所做的操作,以及稍后在 main
中使用 window
的代码将访问通过 SDL_GetWindow
.
获取的资源
但是,C++ 允许您通过使用构造函数和析构函数以更有效的方式管理资源,这个概念称为 RAII(资源获取即初始化)。寻找 SDL 对象周围的 C++ 包装器,这将使您的生活更轻松,如果您不这样做,请花一些时间编写您自己的,或者使它们与 std::unique_ptr
(或 std::shared_ptr
一起工作,如果您知道你需要它)。稍后你会感谢自己的。
我正在用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
从 文件范围 中取出并放入 块范围(即主函数),而不是在这些函数中引用全局变量,我使用参数。
但是,当我尝试 运行 时,它会显示白屏,但不会显示任何错误。我不明白这里出了什么问题。
免责声明:我从来没有做过任何 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' */
}
只有initWindow
中的window
实际设置为SDL_GetWindow
的值。 main
中的 window
变量没有改变:所有其他需要在 main
中使用它的函数将访问一个未初始化的变量,这是未定义的行为。你也有资源泄漏,因为你现在永远无法释放你从 SDL_GetWindow
得到的东西。 initWindow
实际上收到了 window
的 副本 ,与 main
中的 window
完全无关。
看看您是如何使用 C++ 的,最好的解决方法是让 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' */
}
现在,main
中的 window
变量将更新为 initWindow
对其所做的操作,以及稍后在 main
中使用 window
的代码将访问通过 SDL_GetWindow
.
但是,C++ 允许您通过使用构造函数和析构函数以更有效的方式管理资源,这个概念称为 RAII(资源获取即初始化)。寻找 SDL 对象周围的 C++ 包装器,这将使您的生活更轻松,如果您不这样做,请花一些时间编写您自己的,或者使它们与 std::unique_ptr
(或 std::shared_ptr
一起工作,如果您知道你需要它)。稍后你会感谢自己的。