我有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_ptr
或std::shared_ptr
自动管理对Texture对象的破坏。
通过使用指向单独对象的指针,可以避免指向Texture对象的指针无效,因为对象本身没有移动。
或者,您可以使用std::list
而不是std::vector
,因为将对象添加到列表中不会使指向该列表中对象的指针无效。
来自https://en.cppreference.com/w/cpp/container/list:
添加,删除和移动列表中或多个列表中的元素不会使迭代器或引用无效。仅当删除相应的元素时,迭代器才无效。
列表的缺点是它们不提供随机访问权限。