这是一个最小的可重现示例:
#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;
}
解释:该类Label
包装了一个sf::Text
。然后我使用四种不同的方法来初始化和绘制它:
- 局部变量 -> 没有问题
- 指针 -> 没有问题
- 在结构体内部 -> 没有问题
- 指向保存标签的结构的指针 -> PROBLEM
“Label4” 未绘制。我可以看到标签应该出现的点:
为什么指向结构体的指针会导致这个问题?
为了您的方便,这是我用来编译该东西的命令:
g++ test.cc -std=c++20 -lsfml-window -lsfml-system -lsfml-graphics
来自sf::font文档。
此行创建一个,
Label
然后使用它来移动构造Label
内部的另一个Labelstruct
,的主构造函数Label
只运行一次,Font
它拥有的对象被销毁,它被移动到新对象中。但正如文档所说,该对象保留了对被销毁的对象Text
的引用。Font
您的
Label
对象需要存储std::shared_ptr
字体,因此字体引用永远不会失效。请注意
sf::Font
,对象很昂贵。理想情况下,应该在堆栈上(或在资源管理器中)创建字体main
。您的应用程序中应该有 1 个字体对象,并将原始指针传递给您的标签,每个标签没有理由Label
拥有单独的字体。