Este é um exemplo mínimo reproduzível:
#include <memory>
#include <SFML/Graphics.hpp>
class Label
{
public:
Label(sf::String msg, float y)
{
if (!font.loadFromFile("arial.ttf"))
{
printf("Error loading font!\n");
}
text.setString(msg);
text.setPosition(0, y);
}
sf::Font font;
sf::Text text = sf::Text("Label", font, 40);
};
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window");
// label is a local variable
Label label1 = Label("Label1", 0);
// label is inside a pointer
std::unique_ptr<Label> label2 = std::make_unique<Label>("Label2", 50);
struct Labelstruct
{
Label label;
};
// label is inside a struct
struct Labelstruct label3 = { Label("Label3", 100) };
// label is inside a struct inside a pointer:
std::unique_ptr<Labelstruct> label4 = std::make_unique<Labelstruct>(Label("Label4", 150));
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(label1.text);
window.draw(label2->text);
window.draw(label3.label.text);
window.draw(label4->label.text);
window.display();
}
return EXIT_SUCCESS;
}
Explicação: A classe Label
encerra um sf::Text
. Então eu uso quatro maneiras diferentes de inicializá-lo e desenhá-lo:
- Uma variável local -> sem problemas
- Um ponteiro -> sem problemas
- Dentro de uma struct -> sem problemas
- Um ponteiro para a estrutura que contém o rótulo -> PROBLEMA
"Label4" não está desenhado. Posso ver um ponto onde o rótulo deveria aparecer:
Por que um ponteiro para uma struct causa esse problema?
Para sua conveniência, este é o comando que usei para compilar a coisa:
g++ test.cc -std=c++20 -lsfml-window -lsfml-system -lsfml-graphics
da documentação do sf::font .
Esta linha cria um
Label
e o usa para mover-construir outroLabel
que está dentroLabelstruct
, o construtor principal deLabel
é executado apenas uma vez, e oFont
objeto que ele possui é destruído, ele é movido para o novo objeto. mas como os documentos dizem, oText
objeto está mantendo uma referência aoFont
objeto que é destruído.seu
Label
objeto precisa armazenar uma referênciastd::shared_ptr
à fonte, para que a referência à fonte nunca seja invalidada.Observe que
sf::Font
objetos são caros. O ideal é que a fonte seja criada namain
pilha (ou em um gerenciador de recursos). Você deve ter 1 objeto Font em seu aplicativo e passar ponteiros brutos para ele em seus rótulos. Não há razão para que cada umLabel
tenha uma fonte separada.