2

考虑一个 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);
}

现在,当拖动移动时,我可以看到它的位置更新,但 points[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 *>那么它似乎在内存上存储了一个等于 &drag 的地址。

如何使 points[0] 指向 drags[0].pos 并在 drags[0].pos.x 和 drags[0].pos.y 更新时更新其 x,y 值?

如何使 points[0] 成为对drags[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);
4

2 回答 2

3

您不能将引用存储在向量中,但可以存储std::reference_wrapper<ofVec3f>.

std::vector< std::reference_wrapper<ofVec3f> > v;
ofVec3f vec;
v.push_back(std::ref(vec));

存储指针也可以。您只需要使用operator*or正确取消引用它operator->

std::vector< ofVec3f* > pv;
ofVec3f vec;
pv.push_back(&vec);
pv.front()->x;

关于地址相等地址与拖动对象的地址相同是正常的。向量是第一个成员,因此它们具有相同的地址(仅保证 POD 类型实际上是这种情况)。

于 2012-11-23T01:14:19.997 回答
3

您的错误在于认为存储&drag.pos将帮助您跟踪drag' 的位置,而实际上您存储的地址在该范围结束时将变得毫无意义。由于drag是一个局部变量,存在于堆栈中,因此它将在创建它的范围结束时消失。drag即使在这种情况下您无法提供帮助时,也可以存储由向量创建的副本的地址push_back,因为一旦向量的物理大小增长并且必须将其所有内容移动到不同的位置,它也会变得无效记忆。

您可以做的是确保您推送到向量的实际 Drag 对象仍然是唯一的,方法是在堆上分配它并将指向它的(智能)指针推送到向量中。这样,您可以pos像您一样在向量中保留指向其内部的指针,并且只要另一个向量存在,它就会有效。

于 2012-11-23T02:11:54.710 回答