我在粒子系统中有一个名为Spring的类。构造函数如下所示:
Spring(Particle& _a, Particle& _b);
我有一个粒子矢量,我用
Spring mySpring = Spring(myParticles.at(j),myParticles.at(j+1));
在循环内部,在两个粒子之间添加弹力。到目前为止一切正常。 但是,我想使用粒子的2d矢量。那就是:
Spring mySpring = Spring(myParticles.at(i).at(j),myParticles.at(i).at(j+1));
我没有得到粒子的参考。在第一个例子中,每当我在spring类中更改粒子时,向量中的粒子都会发生变化。在第二个示例中,更改仅在本地进行。如何更改2D矢量中的粒子?
编辑: 我试着说清楚一些事情:
我有一些粒子系统,每个粒子系统都由许多粒子组成。每个粒子只应与其自身处于同一系统中的其他粒子相互作用。因此,我有一个粒子系统向量,每个粒子系统都是粒子对象的向量。 (这使得2d矢量)。第一维(i)是系统,第二维(j)是单个粒子。 系统中的粒子相互作用(碰撞,避免,等等......)并且它们的位置发生变化。矢量得到“更新”。 (即参考作品)。
但是,我有第二个(1d)弹簧力矢量。弹簧力也用于更新颗粒的位置。 我的构造函数执行以下操作:
Spring::Spring(Particle& _a, Particle& _b) {
a=&_a;
b=&_b; }
a和b是粒子*。所以我存储指向2d向量中的两个粒子的指针。另一个函数Spring.doSpring()改变了粒子的位置。
a->pos.x=300;
或
a->velocity+=something..
在我发布的第一个例子中,我只使用了一个粒子系统,因此不需要二维矢量。一切正常。向量中的粒子得到更新。 但是第二个例子我的程序运行但不管怎样doSpring函数都会运行,2d向量中的粒子不会更新。
答案 0 :(得分:6)
引用/指向向量内部元素的最常见问题之一是重新分配。例如,如果你使用push_back,那么向量将超过其容量,分配一个新的内存块,复制所有内容,然后释放旧块。如果您已经对向量中的元素进行了引用或指针,那么它们仍然指向旧块,现在是死记忆,并且是一个严重的错误!
所以我猜你的粒子效应会不断向你的粒子向量中添加新粒子,这会导致向量在超出容量时重新分配。 Spring类存储的指针虽然没有更新,但是指向死记忆并且对实际粒子没有影响,实际粒子被矢量移动到其他地方。
不要在向量内部使用引用或指针。使用指针,列表或其他容器的向量,这些容器不会在内存地址周围移动。实际要素。如果必须,请将迭代器用于向量中的元素。在调试版本中,假设您已经检查了STL实现,如果在向量重新分配自身之后通过迭代器访问该元素,您将获得调试警报。
答案 1 :(得分:5)
您正在做的事情看起来没问题 - 以下代码创建了一个“2D”向量,并说明.at()。at()构造确实为您提供了参考:
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector <vector<int> > vi;
vi.push_back( vector <int>() );
vi.at(0).push_back( 42 );
cout << vi.at(0).at(0) << endl; // prints 42
vi.at(0).at(0) = 666;
cout << vi.at(0).at(0) << endl; // prints 666
}
答案 2 :(得分:1)
我认为来自C ++ FAQ Lite的this series应该有所帮助。
请不要被“运算符重载”标题混淆。你绝对应该从那里阅读13.10,13.11和13.12。
答案 3 :(得分:0)
如果我理解正确,您想使用std::vector
创建粒子的2D数组?
如果是这样,您可以将其声明为:std::vector<std::vector<Particle> >
。然后,您甚至可以使用[][]
命名法来访问元素。
( Danger Will Robinson!使用此算子时没有边界检查)
但是,如果这个2D数组主要包含零,则可以使用带有索引的map
作为键。