2012-01-29 6 views
0

私が書いているコードに問題があります。私はこの結果を元にしてこの例に煮詰めました。オブジェクトへのポインタのベクトルのC++の不一致

基本的に、私は1つのクラスで出会って別のクラスに渡すオブジェクトへのポインタのベクトルを持っています。私は、イテレータを使ってこのベクトルを調べることによって、NULLやゴミ値を見つけることができますが、伝統的なfor-loop runthroughを使用するとすべてうまくいくことに気付きました。ここで

はコードです:

#include <iostream> 
#include <vector> 

using namespace std; 

class MyObject 
{ 
    public: 
    int a; 
    int b; 

    MyObject(int _a, int _b) 
    { 
     a = _a; b = _b; 
    } 
}; 

class Builder 
{ 
    public: 
    Builder() { 
     obj_vector.push_back(new MyObject(1, 2)); 
     obj_vector.push_back(new MyObject(3, 4));  
    } 

    vector<MyObject*> getObjectVector() { return obj_vector; } 

    private: 
    vector<MyObject*> obj_vector; 
}; 

class MyObjectHolder 
{ 
    public: 
    MyObjectHolder() 
    { 
     Builder builder; 
     obj_vector = builder.getObjectVector(); 
    } 

    vector<MyObject*> getObjectVector() { return obj_vector; } 

    private: 
    vector<MyObject*> obj_vector; 

}; 

int main() 
{ 
    MyObjectHolder holder; 

    for (vector<MyObject*>::iterator itr = holder.getObjectVector().begin(); itr != holder.getObjectVector().end(); ++itr) 
    { 
     if ((*itr) == NULL) { 
     cout << "NULL" << endl;   
     } 
     else 
     { 
     cout << (*itr)->a << "\t" << (*itr)->b << endl; 
     } 
    } 
    cout << endl; 

    for (unsigned int i = 0; i < holder.getObjectVector().size(); i++) 
    {  
     if (holder.getObjectVector()[i] == NULL) 
     cout << "NULL" << endl; 
     else 
     cout << holder.getObjectVector()[i]->a << "\t" << holder.getObjectVector()[i]->b << endl; 
    } 

    return 0; 
} 

は、このプログラムの出力は次のようになります。イテレータオブジェクトはガベージ値を生成する理由

0 0 
3 4 

1 2 
3 4 

は、だから私は思ったんだけど。他のインスタンスでは、反復子はNULLと等しくなります。私はそれがオブジェクトの間に渡されている間スコープの外に出ているオブジェクトのいくつかと関係があると思っていますが、どこで、なぜか分かりません。新しいvectorを返しholder.getObjectVector()

おかげ

答えて

4

。従ってholder.getObjectVector().begin()holder.getObjectVector.end()は、ループの中にあるようにforとは無関係です。これを修正するだろう参照を返すようにgetObjectVector()を変更

vector<MyObject*>& getObjectVector() { return obj_vector; } 

EDIT:

代替はforループの前に一度getObjectVector()を呼び出し、結果を格納するために配置するだろう、それはないだろう

vector<MyObject*> objs = holder.getObjectVector(); 
for (vector<MyObject*>::iterator itr = objs.begin(); itr != objs.end(); ++itr) 
{ 
    ... 
} 
+0

良い点。参照はここで意図した修正のように見えます。 – Flexo

+0

@awoodlandは、その点を強調するために編集していました。 – hmjd

+0

ああ、とても簡単!面白いことに、私は今までリファレンスを返す理由がなかった。おそらく、なぜベクターのコピーが.begin()と.end()がここで不思議な動作をし、「無関係」という意味であるのかをさらに説明できますか? –

0

私が間違っている場合は私を訂正してくださいあなたのコード内:

class MyObjectHolder 
{ 
    public: 
    MyObjectHolder() 
    { 
     Builder builder; <------ this is on local stack (i.e. gone on constructor exit) 
     obj_vector = builder.getObjectVector(); 
    } 

    vector<MyObject*> getObjectVector() { return obj_vector; } 

    private: 
    vector<MyObject*> obj_vector; <---- so this points to random dynamic memory 

}; 

、それだけでその参照する前に、時にはメモリ位置は、スタック上の他のコードで を使用していないことが起こります。

+0

'Builder :: getObjectVector()'はコピーを返しますので、 'obj_vector'はここで問題ありません。 – hmjd

関連する問題