Today I was writing some SDL C program, with squares called particles. My problem is that, for some reason, variable y in instances of class Particle is always resetting to the value passed into the constructor after incrementing it by 1. I'm storing objects in a list. That's a method called every frame:
void everyFrame(){
this->y =1;
std::cout<<"update y: "<<this->y<<std::endl;
}
And this method is also called every frame, after the everyFrame() method:
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);
}
This is part of the code, where I'm adding an object/objects to the list:
std::list<Particle> particles;
particles.push_back(Particle(2,10,5));
And there I'm executing these 2 methods in the main loop:
for(Particle x:particles){
x.everyFrame();
}
for(Particle x:particles){
x.blit();
}
The console output of the program when y 5 is passed into the constructor is just:
update y: 6
blitting y: 5
looped around. I also found out that when I'm storing an object in a normal variable, not in the list, then it works. Is there any reason/fix for it not working in the list?
CodePudding user response:
These lines:
for(Particle x:particles){
x.everyFrame();
}
are not modifying the particles
list.
This is because Particle x:particles
is creating a copy of each element before calling x.everyFrame()
.
You need to change it to:
for(Particle & x:particles){ // NOTE: added &
x.everyFrame();
}
Taking a refernce to the list element will modify the element in the list.
The same applied to the second loop applying blit()
.
A side note:
Using the auto
keywoard is usually recomended in this case. You need to keep in mind that auto
does not include CV qualifiers, and pointerness/referenceness. Therefore you need:
for(auto & x:particles){ ... }
And if you are traversing a container without modifying the elements, it is rcomended to use:
for(auto const & x:particles){ ... }