不能在块范围内使用 SDL2 变量 [英] Can't use SDL2 variables in Block scope

查看:74
本文介绍了不能在块范围内使用 SDL2 变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 SDL2 进行编程,但我无法理解以下背后的原因.这有效:

I'm programming with SDL2, but I cannot grasp the reason behind the following. This works:

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);
}

唯一的区别是我将windowscreen_surfacepicture文件范围中取出并放入进入块作用域(即主函数),而不是在这些函数中引用全局变量,我使用参数.但是,当我尝试运行它时,它显示白屏,但不显示任何错误.我不明白这里出了什么问题.

The only difference is that I take window, screen_surface and picture out of file scope and put it into block scope (i.e. the main function), and instead of referencing global variables inside these functions, I use parameters. However when I try to run this, it displays a white screen, but doesn't display any errors. I don't understand what goes wrong here.

推荐答案

免责声明:我从未做过任何 SDL 编程,所以这只是基于常识和我从评论中读到的答案.

Disclaimer : I have never done any SDL programming, so this is just an answer based on common sense and what I could read from the comments.

假设您的 initWindow 函数为 window 变量设置了一些值.当在全局范围内声明该变量时,所有其他使用该变量的函数也会看到对其的修改.

Say your initWindow function sets some value to the window variable. When that variable is declared in a global scope, modifications to it are also seen by all the other functions that use this variable.

当您将该变量更改为函数参数时,情况会发生巨大变化.根据您提供的代码:

This changes drastically when you change that variable to be a function parameter. Basing on the code you provided :

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 实际上接收了一个 windowcopy,一个与 main<中的 window 完全无关的/代码>.

Only the window in initWindow is actually set to the value of SDL_GetWindow. The window variable inside main is not changed : all the other functions that need to use it in main will be accessing an uninitialized variable, which is undefined behaviour. You also have a resource leak, since you're now never able to free what you got from SDL_GetWindow. initWindow actually receives a copy of window, a one that's totally unrelated to the window in main.

了解您如何使用 C++,解决此问题的最佳方法是让 initWindow 接受对 window 变量的引用,如下所示:

Seeing how you're using C++, the best way around this is to have initWindow accept a reference to the window variable, like this :

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 对它所做的事情,以及使用 window 的后续代码main 中的 将访问通过 SDL_GetWindow 获取的资源.

Now, the window variable inside main will be updated with what initWindow does with it, and later code that uses window in main will access the resource that was acquired via SDL_GetWindow.

但是,C++ 允许您通过使用构造函数和析构函数以更有效的方式管理资源,这一概念称为 RAII(资源获取即初始化).寻找围绕 SDL 对象的 C++ 包装器,这将使您的生活更轻松,如果您不这样做,请花一些时间来编写自己的,或使它们与 std::unique_ptr(或 std::unique_ptrcode>std::shared_ptr 如果你知道你需要它).以后你会为此感谢自己.

However, C++ allows you to manage resources in a more efficient way via the usage of constructors and destructors, a concept known as RAII (Resource Acquisition Is Initialization). Look for C++ wrappers around the SDL objects which will make your life much easier, and if you don't, spend a while to write your own, or make them work with std::unique_ptr (or std::shared_ptr if you know that you need it). You'll thank yourself for it later on.

这篇关于不能在块范围内使用 SDL2 变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆