参考2d向量中的元素(c ++)

时间:2010-02-05 12:04:28

标签: c++ reference vector

我在粒子系统中有一个名为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向量中的粒子不会更新。

4 个答案:

答案 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作为键。