对象列表中的变量重置问题
Variable resetting problem in a list of objects
今天我正在编写一些 SDL C++ 程序,其中包含称为粒子的正方形。我的问题是,出于某种原因,class Particle 实例中的变量 y 在将其递增 1 后始终重置为传递给构造函数的值。我将对象存储在列表中。
这是每帧调用的方法:
void everyFrame(){
this->y+=1;
std::cout<<"update y: "<<this->y<<std::endl;
}
而且这个方法也是每帧调用,在everyFrame()方法之后:
void blit(){
this->rect.x=this->x*10;
this->rect.y=this->y*10;
std::cout<<"blitting y: "<<this->y<<std::endl;
SDL_BlitSurface(this->image,NULL,screen,&this->rect);
}
这是代码的一部分,我在其中添加了一个 object/objects 到列表中:
std::list<Particle> particles;
particles.push_back(Particle(2,10,5));
我在主循环中执行了这两个方法:
for(Particle x:particles){
x.everyFrame();
}
for(Particle x:particles){
x.blit();
}
将 y 5 传入构造函数时程序的控制台输出为:
update y: 6
blitting y: 5
绕了一圈。
我还发现,当我将对象存储在普通变量中而不是列表中时,它就可以工作了。列表中是否有任何 reason/fix 不起作用?
这些行:
for(Particle x:particles){
x.everyFrame();
}
不是修改particles
列表。
这是因为 Particle x:particles
在调用 x.everyFrame()
之前创建每个元素的副本。
您需要将其更改为:
for(Particle & x:particles){ // NOTE: added &
x.everyFrame();
}
引用列表元素将修改列表中的元素。
这同样适用于应用 blit()
.
的第二个循环
旁注:
在这种情况下,通常建议使用 auto
关键字。您需要记住 auto
不包括 CV 限定符,并且 pointerness/referenceness。因此你需要:
for(auto & x:particles){ ... }
并且如果你是在不修改元素的情况下遍历容器,建议使用:
for(auto const & x:particles){ ... }
今天我正在编写一些 SDL C++ 程序,其中包含称为粒子的正方形。我的问题是,出于某种原因,class Particle 实例中的变量 y 在将其递增 1 后始终重置为传递给构造函数的值。我将对象存储在列表中。 这是每帧调用的方法:
void everyFrame(){
this->y+=1;
std::cout<<"update y: "<<this->y<<std::endl;
}
而且这个方法也是每帧调用,在everyFrame()方法之后:
void blit(){
this->rect.x=this->x*10;
this->rect.y=this->y*10;
std::cout<<"blitting y: "<<this->y<<std::endl;
SDL_BlitSurface(this->image,NULL,screen,&this->rect);
}
这是代码的一部分,我在其中添加了一个 object/objects 到列表中:
std::list<Particle> particles;
particles.push_back(Particle(2,10,5));
我在主循环中执行了这两个方法:
for(Particle x:particles){
x.everyFrame();
}
for(Particle x:particles){
x.blit();
}
将 y 5 传入构造函数时程序的控制台输出为:
update y: 6
blitting y: 5
绕了一圈。 我还发现,当我将对象存储在普通变量中而不是列表中时,它就可以工作了。列表中是否有任何 reason/fix 不起作用?
这些行:
for(Particle x:particles){
x.everyFrame();
}
不是修改particles
列表。
这是因为 Particle x:particles
在调用 x.everyFrame()
之前创建每个元素的副本。
您需要将其更改为:
for(Particle & x:particles){ // NOTE: added &
x.everyFrame();
}
引用列表元素将修改列表中的元素。
这同样适用于应用 blit()
.
旁注:
在这种情况下,通常建议使用 auto
关键字。您需要记住 auto
不包括 CV 限定符,并且 pointerness/referenceness。因此你需要:
for(auto & x:particles){ ... }
并且如果你是在不修改元素的情况下遍历容器,建议使用:
for(auto const & x:particles){ ... }