OH!我发现了这个问题。正如我最后所说,这是一个简单的问题。 在for循环中,我迭代了“粒子”的副本。我更新了它们,但操作不会影响存储在vector中的原始值。
对于有关解决方案的请求,可以使用3种主要方式访问粒子对象。
lvalue-ref
对象方式:
for (auto& p: particles)
...
或通过迭代器:
for (auto it=particles.begin(); i<particles.end();++it)
...
或者通过普通索引:
for (size_t i=0; i<particles.size(); ++i)
...
对于那些对代码感兴趣的人,你可以看一下:
如果我没有遗漏一些非常明显的东西,我遇到了一个非常奇怪的问题。
为了简化问题,我有一个名为“Particle”的类,它有一个名为“update”的函数。粒子类有一些私有变量,如位置,速度等。更新函数应该进行一些计算并为该私有变量添加适当的值。但是,这根本行不通。
实际上,我对这个变量的类型持怀疑态度,这是我写的一个类,“Vector2”。
要为变量添加值,我使用了“+ =”运算符,我想我在Vector2类中正确实现了它们(?)。
为了澄清情况,恕我直言,最好给出一些代码:
这是我的Vector2.h:
namespace sim {
#include <ostream>
#include <cmath>
using namespace std;
struct Vector2 {
double x, y;
Vector2& operator+=(const Vector2& rhs) {
this->x += rhs.x;
this->y += rhs.y;
cout << "op+=" << endl;
return *this;
}
Vector2& operator*=(double k) {
x *= k;
y *= k;
cout << "op*=" << endl;
return *this;
}
friend ostream& operator<<(ostream& os, const Vector2& v2);
friend Vector2 operator+(Vector2 lhs, const Vector2& rhs);
friend Vector2 operator-(Vector2 lhs, const Vector2& rhs);
friend Vector2 operator*(Vector2 lhs, double k);
friend Vector2 operator*(double k, Vector2 rhs);
};
ostream& operator<<(ostream& os, const Vector2& v2) {
os << "[ " << v2.x << "; " << v2.y << " ]";
return os;
}
Vector2 operator+(Vector2 lhs, const Vector2& rhs) {
lhs += rhs;
cout << "op+" << endl;
return lhs;
}
Vector2 operator*(Vector2 lhs, double k) {
lhs *= k;
cout << "op*" << endl;
return lhs;
}
(删除了一些不相关的部分,如构造函数)
这是粒子类:
class Particle {
private:
Vector2 pos;
Vector2 vel;
Vector2 acc;
double rad;
SDL_Color clr;
public:
Particle(
Vector2 _p,
Vector2 _v,
Vector2 _a,
double _r = 10.0,
SDL_Color _c = { 255, 255, 255, 255 }) {
pos = _p;
vel = _v;
acc = _a;
rad = _r;
clr = _c;
}
Vector2& move_particle(Vector2 move_by) {
return (pos += move_by);
}
void update(double dt) {
this->vel += acc * dt;
this->pos += vel * dt;
cout << "update " << pos << vel << acc << endl;
}
void render(SDL_Renderer* renderer) {
// TODO: this was supposed to be a circle, but, who cares? ;)
SDL_Rect r = { int(pos.x), int(pos.y), int(rad), int(rad) };
SDL_RenderFillRect(renderer, &r);
cout << "render" << endl;
}
};
结果:更新没有更新。
对于3个Vector2
个对象,我可以进行正确定义的任何操作。
结果就是他们应该做的。 (或者,也许不是?)
但调试更新函数大致让我发现实际上+ =运算符一次有效,而不是再次但是这种行为只在更新函数中显示出来。
我知道,这将是一个如此简单的错误,我可能感到羞耻(只是开玩笑)。
哦,主要代码当然是:
int main() {
SDL_Init(SDL_INIT_EVERYTHING);
auto window = SDL_CreateWindow("My Very First Particle Simulation", -1, -1,
1024, 768, SDL_WINDOW_SHOWN);
auto renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
const Vector2 g(0.0, 9.8);
double dt = 0.1;
std::vector<Particle> particles;
bool quit = false;
while (!quit) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
quit = true;
break;
case SDL_MOUSEBUTTONUP:
particles.emplace_back(Vector2(event.button.x, event.button.y), Vector2(1.0, 0.0), g);
break;
default:
break;
}
SDL_RenderClear(renderer);
for (auto p : particles) {
p.update(dt);
p.render(renderer);
}
SDL_RenderPresent(renderer);
}
}
}
答案 0 :(得分:0)
对您的代码提出一些意见, 你可以把它们改成成员函数
friend Vector2 operator+(Vector2 lhs, const Vector2& rhs);
friend Vector2 operator-(Vector2 lhs, const Vector2& rhs);
friend Vector2 operator*(Vector2 lhs, double k);
friend Vector2 operator*(double k, Vector2 lhs);
,如
Vector2 operator+(const Vector2& rhs);
Vector2 operator-(const Vector2& rhs);
Vector2 operator*(const double k);
friend Vector2 operator*(const double k, Vector2 lhs);
在其中将this
复制到新的Vector2
,然后更新该值并返回。第四个函数保留为朋友,这样你就可以拥有像double * Vector2这样的东西,而第三个函数可以处理Vector2 * double
将Vector2作为左操作数的任何操作都可以作为成员函数完成。
答案 1 :(得分:-1)
我可以看到这两个运算符正在按值计算它们的第一个args。更改它们以便通过引用获取它们的参数。
Vector2 operator+(Vector2 lhs, const Vector2& rhs) { // lhs should be a const reference
lhs += rhs;
cout << "op+" << endl;
return lhs;
}
Vector2 operator*(Vector2 lhs, double k) { // lhs should be a const reference
lhs *= k;
cout << "op*" << endl;
return lhs;
}
修改强>
这些函数也应该将它们的类args作为const
referenecs:
friend Vector2 operator+(Vector2 lhs, const Vector2& rhs);
friend Vector2 operator-(Vector2 lhs, const Vector2& rhs);
friend Vector2 operator*(Vector2 lhs, double k);
friend Vector2 operator*(double k, Vector2 rhs);