全局变量超出范围!有没有搞错?

Mar*_*kas 0 c++ scope global sfml

休斯顿,我们有一个问题.这是一个简化的代码版本:

main.cpp中

#include <SFML/Graphics.hpp>
#include "global.hpp"
#include "init.hpp"
int main(void)
{
    createWindow();
    loadLevel();

    while(window.isOpen())
    {
        if(!handleEvents()) window.close();
        window.clear();
        window.draw(bgSprite);
        window.display();
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

global.hpp

sf::Texture      bgTexture;
sf::Sprite       bgSprite;
Run Code Online (Sandbox Code Playgroud)

init.hpp

void loadGraphics(void)
{
    bgTexture.loadFromFile("bg.png");
    bgSprite.setTexture(bgTexture);
}
Run Code Online (Sandbox Code Playgroud)

即使纹理和子画面变量是全局的,窗口屏幕仍然是黑色的.但是,当我将变量放在main()函数中时,一切都很完美.有人可以解释为什么会这样吗?

我认为你可以随时随地调用全局变量,只有当程序本身终止时它们才会消失.

顺便说一句,我也尝试将变量和loadGraphics()放在main()后面(不在头文件中),仍然没有结果.我还注释掉了所有其他代码,所以问题肯定在这里.

编辑:我是个傻瓜!

我没有调用loadGraphics(函数).谢谢!我很抱歉你浪费了时间.一切都开始正常.伤心的哈哈 - 花了1个多小时修理这个东西......

Mik*_*our 5

你永远不会调用loadGraphics.在开始时调用它main,您的程序可能会工作.

但是如果没有全局变量,你几乎肯定会变得更好; 并且在任何情况下,您都不希望在标题中定义它们,因为如果您在程序中多次包含该标题,则会破坏单一定义规则.

如果你真的希望它们是全局的,那么在标题中声明它们(不要定义它们):

extern sf::Texture bgTexture;
Run Code Online (Sandbox Code Playgroud)

并在一个源文件中定义它们(就像你已经完成的那样).

同样,出于同样的原因,您不应在标头中定义非内联函数.将其保留在标题中并使其内联:

inline void loadGraphics()     // void parameter is pointless
{
    bgTexture.loadFromFile("bg.png");
    bgSprite.setTexture(bgTexture);
}
Run Code Online (Sandbox Code Playgroud)

或者只是在标题中声明它

void loadGraphics();
Run Code Online (Sandbox Code Playgroud)

并将您的定义移动到源文件中.

您可以通过将它们封装在类中来避免全局变量:

struct Graphics {
    Graphics(std::string file) {
        texture.loadFromFile(file);
        sprite.setTexture(texture);
    }

    sf::Texture texture;
    sf::Sprite sprite;
};
Run Code Online (Sandbox Code Playgroud)

并在中实例化 main

Graphics graphics("bg.png");
//...
window.draw(graphics.sprite);
Run Code Online (Sandbox Code Playgroud)