C ++存储对向量中类成员的引用

时间:2012-11-23 01:02:20

标签: c++ pointers reference openframeworks

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

2 个答案:

答案 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的指针,就像你做的那样,只要另一个向量是有效的,它就会有效。