SFML 纹理无法正确加载



我得到了A类,可以访问所有标准的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;
};

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

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

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

为了解决此问题,我建议在 A 类中使用某种类型的指针指向tex对象。
可以使用指向在构造函数中使用new创建的 Texture 对象的原始指针。但请务必在析构函数中delete对象。
或者,您可以使用std::unique_ptrstd::shared_ptr来自动管理 Texture 对象的销毁。

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

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

从 https://en.cppreference.com/w/cpp/container/list:

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

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

最新更新