无法在块范围

时间:2016-02-10 23:57:35

标签: c++ sdl sdl-2

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

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

1 个答案:

答案 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副本,这个windowmain中的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 = ?如果您一起工作知道你需要它)。你以后会感谢自己。