考虑一个Drag对象:
class Drag {
public:
Drag(ofVec3f _pos);
ofVec3f pos;
}
创建新实例时会存储位置:
Drag::Drag(ofVec3f _pos) {
pos = _pos;
}
鼠标移动时位置会更新:
void Drag::mouseMoved() {
pos.x = ofGetMouseX();
pos.y = ofGetMouseY();
}
在应用程序的主类(openframeworks中的testApp)中:
class testApp : public ofBaseApp {
public:
vector<Drag> drags;
vector<ofVec3f *> points;
}
按下鼠标时创建一个Drag并将其位置存储在一个名为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);
}
现在当移动拖动时,我可以看到它的位置更新,但是点[0]没有改变:
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;
}
如果点类型为vector<ofVec3f>
,则点[0]似乎是初始拖动[0] .pos的副本。如果它是vector<ofVec3f *>
那么它似乎在内存上存储了一个等于&amp; drag的地址。
如何更新[0]指向拖动[0] .pos并在更新拖动[0] .pos.x和drags [0] .pos.y时更新其x,y值?
如何让积分[0]成为参考来拖动[0] .pos?
编辑:感谢yonilevy指出我正确的方向。这是使用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);
答案 0 :(得分:3)
您无法在向量中存储引用,但可以存储std::reference_wrapper<ofVec3f>
。
std::vector< std::reference_wrapper<ofVec3f> > v;
ofVec3f vec;
v.push_back(std::ref(vec));
存储指针也可以。您只需要使用operator*
或operator->
正确取消引用它。
std::vector< ofVec3f* > pv;
ofVec3f vec;
pv.push_back(&vec);
pv.front()->x;
关于地址相等性地址与拖拽对象的地址相同是正常的。向量是第一个成员,因此它们具有相同的地址(这实际上只是POD类型的情况)。
答案 1 :(得分:3)
您的错误在于认为存储&drag.pos
将帮助您跟踪drag
的位置,而实际上您存储的地址在该范围的末尾将变得毫无意义。由于drag
是一个居住在堆栈上的局部变量,因此它将在创建它的作用域的末尾消失。在这种情况下,即使存储由drag
向量创建的push_back
副本的地址也无济于事,因为一旦向量增长,它也将变为无效,并且必须将所有内容移到内存中的不同位置。
你可以做的是确保你推送到向量的实际Drag对象仍然是唯一的,通过在堆上分配并将(智能)指针推送到向量中。这样,你就可以在向量中保持一个指向其内部pos
的指针,就像你做的那样,只要另一个向量是有效的,它就会有效。