Ложится программа при запуске

192
28 апреля 2018, 18:11

В общем есть код

#include <SFML\Graphics.hpp>
#include <string>
namespace game {
    const sf::Vector2u WINDOW_SIZE(256,240);
    int scaleCoeff = 2;

    class ImageResource
    {
    public:
        ImageResource(std::string url);
        sf::Image image;
        sf::Texture texture;
        sf::Sprite sprite;
    };
    ImageResource::ImageResource(std::string url)
    {
        this->image.loadFromFile(url);
        this->texture.loadFromImage(this->image);
        this->sprite.setTexture(this->texture);
    }
    ImageResource logo("logo.png");
}

int main()
{
    sf::RenderWindow app(sf::VideoMode(game::WINDOW_SIZE.x, game::WINDOW_SIZE.y), "!Curse");
    app.setSize(sf::Vector2u(game::WINDOW_SIZE.x * game::scaleCoeff, game::WINDOW_SIZE.y * game::scaleCoeff));

    while (app.isOpen())
    {
        sf::Event ev;
        while (app.pollEvent(ev))
        {
            if (ev.type == sf::Event::Closed)
                app.close();
        }
        app.clear();
        app.draw(game::logo.sprite);
        app.display();
    }
}

Дело в том что компилятор ни на что не ругается, но при запуске программы она просто ложится. Я выяснил что проблема заложена в классе ImageResource. Я даже указатели не использовал как программа крашится моментально.

Answer 1

Не создавайте графические объекты SFML глобальными статическими. В данном случае проблема заключается в том, что переменная logo именно глобальная статическая. Для статических глобальных переменных, расположенных в разных единицах трансляции порядок инициализации не определен. Вы наткнулись на так называемое static order initialization fiasco. Неизвестно, что будет прежде - инициализация logo или инициализация SFML. В Вашем случае, видимо, сначала инициализируется logo, и, соответственно, используется еще не готовая к работе SFML.

Сделайте переменную logo локальной переменной в main, это исключит инициализацию logo до SFML, т.к. при вызове main все статические глобальные данные уже инициализированы.

//...
int main()
{
   game::ImageResource logo("logo.png");
   //...
   app.draw(logo.sprite);
   //...
}

Если действительно необходима глобальная точка доступа к ресурсу, то можете обернуть статический объект в функцию, которая возвращает ссылку на ресурс:

namespace game {
    //...
    ImageResource & getLogo() 
    {
        static ImageResource logo("logo.png");
        return logo;
    }
}
//...
int main()
{
   //...
   app.draw(game::getLogo().sprite);
   //...
}

P.S. И не забывайте про обработку ошибок.

READ ALSO
Не перегружается оператор &ldquo;&gt;&gt;&rdquo;

Не перегружается оператор “>>”

не получается перегрузить оператор вводаВыскакивает ошибка:

186
Отменяет ли регистрацию класса окна PostQuitMessage

Отменяет ли регистрацию класса окна PostQuitMessage

Когда мое приложение стартует, RegisterClassEx иногда возвращает 0, и приложение приходится аварийно завершатьЭто происходит не по тому ли что иногда...

148
Как динамически с помощью переменных и регулярного выражения поменять последнее значение в строке?

Как динамически с помощью переменных и регулярного выражения поменять последнее значение в строке?

Нужно динамически с помощью переменных и регулярного выражения поменять последнее значение в строкеВ первом случае работает во втором нет

195