C++ Can';t在块范围中使用SDL2变量

C++ Can';t在块范围中使用SDL2变量,c++,sdl,sdl-2,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();

我正在使用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);
}
唯一的区别是,我将
窗口
屏幕表面
图片
移出文件范围,并将其放入块范围(即主函数),而不是引用这些函数中的全局变量,而是使用参数。
但是,当我尝试运行它时,它会显示一个白色屏幕,但不会显示任何错误。我不明白这里出了什么问题

免责声明:我从未做过任何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
中的
窗口实际上设置为
SDL\u GetWindow
的值。
main
中的
窗口
变量未更改:在
main
中需要使用它的所有其他函数将访问未初始化的变量,这是未定义的行为。您还存在资源泄漏,因为您现在无法从
SDL\u GetWindow
中释放所获得的资源
initWindow
实际上收到了
window
副本,该副本与
main
中的
窗口
完全无关

参见如何使用C++,最好的方法是使用<代码> iTwitter窗口<代码>接受对“代码>窗口变量的引用,如下所示:

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\u GetWindow
获取的资源


但是,C++允许您通过使用构造函数和析构函数来更有效地管理资源,一个被称为RAII(资源获取是初始化)的概念。寻找SDL对象周围的C++包装,这将使你的生活变得更容易,如果你不愿意,花一段时间写自己的文章,或者让它们与 STD::UnQuyJPPT(或者<代码> STD::SysDypPTR < /代码>,如果你知道你需要它)。稍后您会为此感谢自己。

免责声明:我从未做过任何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
中的
窗口实际上设置为
SDL\u GetWindow
的值。
main
中的
窗口
变量未更改:在
main
中需要使用它的所有其他函数将访问未初始化的变量,这是未定义的行为。您还存在资源泄漏,因为您现在无法从
SDL\u GetWindow
中释放所获得的资源
initWindow
实际上收到了
window
副本,该副本与
main
中的
窗口
完全无关

参见如何使用C++,最好的方法是使用<代码> iTwitter窗口<代码>接受对“代码>窗口变量的引用,如下所示:

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\u GetWindow
获取的资源


但是,C++允许您通过使用构造函数和析构函数来更有效地管理资源,一个被称为RAII(资源获取是初始化)的概念。寻找SDL对象周围的C++包装,这将使你的生活变得更容易,如果你不愿意,花一段时间写自己的文章,或者让它们与 STD::UnQuyJPPT(或者<代码> STD::SysDypPTR < /代码>,如果你知道你需要它)。你以后会感谢你自己的。

很适合用IDE的调试器对这两个版本进行调试,看看有什么不同。什么是
void f(int x){x=5;}
int main(){int i=7;f(i);printf(“%d\n”,i)}
print,为什么?详细说明
initWindow(SDL_Window*Window,SDL_Surface*screen_Surface)
您正在传递此声明中指针的副本。@henrikgiesel否?C没有引用调用。@henrikgiesel:是的,在调用
initWindow
函数之前,它们指向内存中的同一点。但是,在
initWindow
中,您可以更改复制的指针指向的对象。问题是,这不会影响在
main
中声明的指针,您只是在
initWindow
中修改复制的指针。使用IDE的调试器单步检查这两个版本以查看区别是什么。什么是
void f(int x){x=5;}
int main(){int i=7;f(i);printf(%d\n,i);}
print,为什么?要详细说明
initWindow(SDL\u Window*Window,SDL\u Surface*screen\u Surface)
您正在传递此声明中指针的副本。@henrikgiesel No?C没有引用调用这种东西。@henrikgiesel:是的,在调用之前,它们指向内存中的同一点