SFML纹理无法正确加载

问题描述 投票:0回答:1

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

c++ textures sfml stdvector
1个回答
0
投票

通过调用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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.