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

时间:2014-12-19 16:56:40

标签: 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;
}

global.hpp

sf::Texture      bgTexture;
sf::Sprite       bgSprite;

init.hpp

void loadGraphics(void)
{
    bgTexture.loadFromFile("bg.png");
    bgSprite.setTexture(bgTexture);
}

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

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

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

编辑:我是个白痴!

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

3 个答案:

答案 0 :(得分:5)

您永远不会致电loadGraphics。在main开始时调用它,您的程序可能会正常工作。

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

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

extern sf::Texture bgTexture;

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

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

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

或只是在标题中声明它

void loadGraphics();

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

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

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

    sf::Texture texture;
    sf::Sprite sprite;
};

并在main

中实例化
Graphics graphics("bg.png");
//...
window.draw(graphics.sprite);

答案 1 :(得分:3)

当您将变量global设置为项目时,需要将其放在.cpp文件中并生成.h,将其声明为extern。这允许所有文件引用相同的全局变量。

在您的情况下,您可以更改代码:

<强> global.hpp

extern sf::Texture bgTexture;
extern sf::Sprite  bgSprite;

<强> global.cpp

sf::Texture      bgTexture;
sf::Sprite       bgSprite;

此外,与Mike's answer一样,您永远不会致电loadGraphics()

就个人而言,我将其放在另一个.cpp文件中并将.hpp文件放在原型中。

此外,在编译时,您必须将所有cpp文件一起编译为单个可执行文件(即将它们链接在一起)

答案 2 :(得分:1)

永远不会设置

bgTexturebgSprite。我在loadGraphics中看不到您对main功能的任何来电。

您应该先致电loadGraphics函数