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>points[0] は最初の drags[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

&drag.posあなたの間違いは、格納すると の位置を追跡するのに役立つと考えるdragことにありますが、実際には、そのスコープの終わりまでに無意味になるアドレスを格納しています。dragはスタック上に存在するローカル変数であるため、作成されたスコープの終わりまでになくなります。dragこの場合、ベクターによって作成されているコピーのアドレスを保存してpush_backも、ベクターの物理サイズが大きくなり、そのすべてのものを別の場所に移動する必要があるため、無効になります。メモリー。

あなたができることは、ベクトルにプッシュする実際の Drag オブジェクトが、ヒープに割り当て、(スマート) ポインターをベクトルにプッシュすることによって、唯一のオブジェクトのままであることを確認することです。そうすれば、同じように内部へのポインターをposベクターに保持でき、他のベクターが有効である限り有効になります。

于 2012-11-23T02:11:54.710 に答える
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;

アドレスの等価性についてドラッグオブジェクトのアドレスとアドレスが同じであることは正常です。vector は最初のメンバーであるため、同じアドレスを持ちます (これは、実際に POD 型の場合にのみ保証されます)。

于 2012-11-23T01:14:19.997 に答える