C ++与对象指针向量的差异

时间:2012-01-29 00:03:33

标签: c++ object pointers vector

我在写一段代码时遇到了问题。我把它归结为这个例子,它产生了相同的结果(原则上)。

基本上我有一个指向对象的指针,我在一个类中遇到它,并传递给另一个类。然后我注意到通过使用迭代器遍历此向量,我遇到了NULL或垃圾值,而使用传统的for循环遍历一切都很好。

以下是代码:

#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。我猜它与某些在对象之间传递的对象超出范围有关,但我无法弄清楚在哪里或为什么。

由于

2 个答案:

答案 0 :(得分:4)

holder.getObjectVector()会返回新的vector。因此holder.getObjectVector().begin()holder.getObjectVector.end()不相关,如for循环中所存在的那样。

更改getObjectVector()以返回引用将更正此问题:

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

编辑:

另一种方法是安排在getObjectVector()循环之前调用for一次并存储结果,并且没有必要返回引用:

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

答案 1 :(得分: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

};

并且恰好有时候不使用内存位置 在引用它之前通过堆栈上的其他代码。