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

hrs*_*rst 5 c++ reference vector

我在粒子系统中有一个名为Spring的类.构造函数看起来像:

Spring(Particle& _a, Particle& _b);
Run Code Online (Sandbox Code Playgroud)

我有一个粒子矢量,我使用

Spring mySpring = Spring(myParticles.at(j),myParticles.at(j+1));
Run Code Online (Sandbox Code Playgroud)

在一个循环内部,在两个粒子之间增加一个弹力.到目前为止一切正常.但是,我想使用粒子的2d矢量.那是:

Spring mySpring = Spring(myParticles.at(i).at(j),myParticles.at(i).at(j+1));
Run Code Online (Sandbox Code Playgroud)

而且我没有得到粒子的参考.在第一个例子中,每当我在spring类中更改粒子时,向量中的粒子都会发生变化.在第二个示例中,更改仅在本地进行.如何更改2D矢量中的粒子?

编辑:我试着说清楚一些事情:

我有一些粒子系统,每个粒子系统都由许多粒子组成.每个粒子只应与其自身处于同一系统中的其他粒子相互作用.因此,我有一个粒子系统向量,每个粒子系统都是粒子对象的向量.(这使得2d矢量).第一维(i)是系统,第二维(j)是单个粒子.系统中的粒子相互作用(碰撞,避免,等等......)并且它们的位置发生变化.矢量得到"更新".(即参考作品).

但是,我有第二个(1d)弹簧力矢量.弹簧力也用于更新颗粒的位置.我的构造函数执行以下操作:

Spring::Spring(Particle& _a, Particle& _b) {
    a=&_a;
    b=&_b; }
Run Code Online (Sandbox Code Playgroud)

a和b是粒子*.所以我存储指向2d向量中的两个粒子的指针.另一个函数Spring.doSpring()改变了粒子的位置.

a->pos.x=300;
Run Code Online (Sandbox Code Playgroud)

要么

a->velocity+=something..
Run Code Online (Sandbox Code Playgroud)

在我发布的第一个例子中,我只使用了一个粒子系统,因此不需要二维矢量.一切正常.向量中的粒子得到更新.但是第二个例子我的程序运行但不管doSpring函数做了什么,2d向量中的粒子都没有得到更新.

Ash*_*ain 6

采用引用/指向向量内部元素的最常见问题之一是重新分配.例如,如果你使用push_back,那么向量将超过其容量,分配一个新的内存块,复制所有内容,然后释放旧块.如果您已经对向量中的元素进行了引用或指针,那么它们仍然指向旧块,现在是死记忆,并且是一个严重的错误!

所以我猜你的粒子效应会不断向你的粒子向量添加新的粒子,这在某些时候会导致向量在超出容量时重新分配.Spring类存储的指针虽然没有更新,但是指向死记忆并且对实际粒子没有影响,实际粒子被矢量移动到其他地方.

不要将引用或指针指向向量内的元素.使用指针,列表或其他容器的向量,它不会在实际元素的内存地址周围移动.如果必须,请使用迭代器到向量内的元素.在调试版本中,假设您已经检查了STL实现,如果在向量重新分配自身后通过迭代器访问该元素,您将获得调试警报.


小智 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
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*Gil 0

如果我理解正确的话,你想使用创建一个二维粒子数组std::vector

如果是这样,您可以将其声明为:std::vector<std::vector<Particle> >。然后,您甚至可以使用[][]命名法来访问元素。(危险威尔·罗宾逊!使用此操作符时不进行边界检查

map但是,如果这个 2D 数组主要包含零,那么使用带有索引作为键的a 可能是可以的。