SFML 纹理未正确加载

SFML texture not loading propely

我 class 可以访问所有标准 SFML 内容:

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;
};

在另一个 class 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() 调用它,它只加载了第一个,而不是第二个。这是非常奇怪的行为,我不知道是什么原因造成的。

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

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

网站 https://en.cppreference.com/w/cpp/container/vector 在 "Iterator invalidation" 下显示了使用 std::vector.

时哪些迭代器(基本上是指针)通过哪些方法无效

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

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

通过使用指向单独对象的指针,可以避免指向 Texture 对象的指针失效,因为对象本身没有移动。

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

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

Adding, removing and moving the elements within the list or across several lists does not invalidate the iterators or references. An iterator is invalidated only when the corresponding element is deleted.

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