2014-12-19 5 views
0

Хьюстон, у нас есть проблема. Вот упрощенная версия кода:Глобальная переменная выходит за рамки! Какого черта?

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() (не в заголовочном файле), тем не менее, никаких результатов. Я также прокомментировал весь дополнительный код, поэтому проблема определенно лежит здесь.

EDIT: Я ИДЕТ!

Я не назвал loadGraphics (function). Спасибо! Прошу прощения за потраченное время. Все началось правильно. Грустный lol - потратил более 1 часа на крепление этой вещи ...

+0

@MikeSeymour Хорошо, гипотеза одна удалена. Объявление глобалов в заголовочном файле без соответствующей «реализации» кажется более чем немного отрывочным. – tadman

+0

Пробовал использовать внешний. В журнале ошибок перечислены четыре неопределенные ссылки, либо на bgTexture, либо на bgSprite –

+0

Я проголосовал за закрытие этого вопроса сейчас, так как он вряд ли поможет в любых будущих исследованиях (помимо напоминания другим, чтобы проверить, действительно ли они назовут их функции). –

ответ

5

Вы никогда не звоните loadGraphics. Позвоните, что в начале main, и ваша программа, вероятно, сработает.

Но вы почти наверняка будете лучше без глобалов; и в любом случае вы не хотите определять их в заголовке, так как это нарушит правило One Definition, если вы включите этот заголовок более одного раза в свою программу.

Если вы действительно хотите, чтобы быть глобальным, то объявить их (без definining их) в заголовке:

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

bgTexture и bgSprite никогда не установлены. Я не вижу никакого вызова вашей функции loadGraphics в main.

Вы должны начать с вызова вашей loadGraphics функции

3

Когда вы размещаете переменные глобальной в проект, вы должны поместить его в файл .cpp и сделать .h, который декларирует как экстерн. Это позволяет всем файлам ссылаться на одну и ту же глобальную переменную.

В вашем случае, вы бы изменить код, так:

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 файлы в единый исполняемый файл (т.е. связать их вместе)

Смежные вопросы