Consider a Drag object:
class Drag {
public:
Drag(ofVec3f _pos);
ofVec3f pos;
}
Position is stored when a new instance is created:
Drag::Drag(ofVec3f _pos) {
pos = _pos;
}
Position is updated when mouse moves:
void Drag::mouseMoved() {
pos.x = ofGetMouseX();
pos.y = ofGetMouseY();
}
In the application’s main class (testApp in openframeworks):
class testApp : public ofBaseApp {
public:
vector<Drag> drags;
vector<ofVec3f *> points;
}
Create a Drag when the mouse is pressed and store its position in a vector called points:
void testApp::mousePressed(int x, int y, int button) {
Drag drag = Drag(ofVec3f(ofGetMouseX(), ofGetMouseY(), 0));
drags.push_back(drag);
points.push_back(&drag.pos);
}
Now when the drag is moved, I can see its position update, but points[0] doesn’t change:
void testApp::update(){
if (!drags.size()) return;
cout << drags[0].pos.x << ", " << drags[0].pos.y << endl;
cout << &points[0]->x << ", " << &points[0]->y << endl;
}
If the type of points is vector<ofVec3f> it seems that points[0] is a copy of the initial drags[0].pos. If it is vector<ofVec3f *> then it seems to store an address on memory that is equal to &drag.
How can I make points[0] point to drags[0].pos and get its x,y values updated when drags[0].pos.x and drags[0].pos.y are updated?
How can I make points[0] be a reference to drags[0].pos?
Edit: Thanks to yonilevy for pointing me in the right direction. Here’s the working example, updated using std::list:
// testApp.h
list<Drag> drags;
vector<ofVec3f *> points;
// testApp::mousePressed
drags.push_back(Drag(ofVec3f(ofGetMouseX(), ofGetMouseY(), 0)));
points.push_back(&drags.back().pos);
Your mistake is in thinking storing
&drag.poswill help you keep track ofdrag‘s position, while in fact you are storing an address that will become meaningless by the end of that scope. Sincedragis a local variable, living on the stack, it will be gone by the end of the scope in which it was created. Even storing the address of the copy ofdragthat’s being created by the vector when youpush_backwon’t help in this case, since it will also become invalid once the vector grows in physical size and has to move all of its stuff to a different place in memory.What you could do, is make sure the actual Drag object you push to the vector remains the only one around, by allocating it on the heap and pushing a (smart) pointer to it into the vector. That way, you can keep a pointer to its internal
posin a vector just like you did, and it will be valid as long as the other vector is.