【问题标题】:SFML texture not loading propelySFML 纹理未正确加载
【发布时间】:2020-05-29 22:17:13
【问题描述】:

我获得了可以访问所有标准 SFML 内容的 A 类:

class A{
public:
A(int type, Vector2f pos){
if(type == 1) tex.loadFromFile(path1);
else if(type == 2) tex.loadFromFile(path2); 
//etc. etc.
shape.setTexture(&tex);

//then I set up the radius, and the position (from the constructor)
//I debugged this part and it seemed to work so I wont bother typing it out
};


Texture tex;
CircleShape shape;
};

在另一个 B 类中,我得到了 A 的 std::vector:

 class B{
 public:
 void update(){
 //under a bunch of conditions
 list.push_back(A(1,Vector2f(100,100)); //examples
 list.push_back(A(1,Vector2f(200,200))
 }
 std::vector<A> list;
 };

无论如何,纹理无法正确加载,我只剩下白色球体。我尝试将它放在一个单独的函数中并使用back() 调用它,它只加载了第一个,而不是第二个。这是非常奇怪的行为,我不知道是什么原因造成的。

【问题讨论】:

标签: c++ textures sfml stdvector


【解决方案1】:

通过调用shape.setTexture(&amp;tex),指向您的纹理对象的指针存储在形状中。

问题是您正在使用std::vector 来管理您的 A 对象。 std::vector 管理堆上的一个数组。但是这个数组不是动态的,它不能改变它的大小。因此,为了增加它的大小,向量分配一个具有所需大小的全新数组,将旧数组中的元素复制到新数组中并删除旧数组。
现在,Shape 对象内的指针已失效,因为它尚未更新,它现在指向一个可以包含任何内容的内存位置。

网站https://en.cppreference.com/w/cpp/container/vector 在“迭代器失效”下显示了使用std::vector 时哪些迭代器(基本上是指针)通过哪些方法失效。

这就是您的纹理无法正常工作的原因。

为了解决这个问题,我建议在 A 类中使用某种指向 tex 对象的指针。
您可以使用原始指针指向您在构造函数中使用new 创建的纹理对象。但一定要delete析构函数中的对象。
作为替代方案,您可以使用std::unique_ptr 或std::shared_ptr 来自动管理纹理对象的销毁。

通过使用指向单独对象的指针,可以避免指向纹理对象的指针无效,因为对象本身不会移动。

或者,您可以使用std::list 而不是std::vector,因为将对象添加到列表不会使指向该列表中对象的指针无效。

来自https://en.cppreference.com/w/cpp/container/list:

在列表中或跨多个列表添加、删除和移动元素不会使迭代器或引用无效。只有当相应的元素被删除时,迭代器才会失效。

列表的缺点是它们不提供随机访问。

【讨论】:

  • 感谢您的深刻回答,我完全没有意识到这一点。然而,自从我发布了这个问题后,我就解决了这个问题,尽管是以一种不太理想的方式。
猜你喜欢
  • 2021-08-31
  • 2014-08-13
  • 2020-07-23
  • 1970-01-01
  • 1970-01-01
  • 2015-12-22
  • 1970-01-01
  • 2020-07-21
  • 2021-02-01
相关资源
最近更新 更多