类成员向量上的迭代器未正确解除引用

时间:2012-08-27 12:02:16

标签: c++ iterator stdvector

我有一个名为Domain的类,它有一个受保护的成员std::vector itsVec。可以通过getVec()访问该向量。

main()中,当我通过直接寻址元素时,它可以正常工作 getVec()[i]。但是,当我尝试使用迭代器时,指针指向第一个 元素似乎没有正确初始化。奇怪的是,在类构造函数中使用itsVec上的迭代器就像一个魅力。

代码

#include<iostream>
#include <vector>

class Domain
{
  public:
    /* ====================  LIFECYCLE     ======================================= */
    Domain  ( ) {};                                    /* constructor        */
    Domain  ( unsigned int , const unsigned int * ) ;  /* custom constructor */
    Domain  ( const Domain &other );                   /* copy constructor   */
    ~Domain ( ) {};                                    /* destructor         */

    /* ====================  ACCESSORS     ======================================= */
    unsigned int              getDim() const {return itsDim;}
    std::vector<unsigned int> getVec() const {return itsVec;}

  protected:
    /* ====================  DATA MEMBERS  ======================================= */
    unsigned int              itsDim;
    std::vector<unsigned int> itsVec;

}; /* -----  end of class Domain  ----- */


Domain::Domain( unsigned int dim, const unsigned int  *externVec)
{
  itsDim = dim;

  for ( size_t j = 0; j < dim ; j++ )
    itsVec.push_back(externVec[j]);

  std::vector<unsigned int>::const_iterator i_vec  = itsVec.begin();

// iterator access works
  for ( ; i_vec != itsVec.end(); i_vec++) 
    std::cout<<"Iterator in constructor: " << (*i_vec) << std::endl;

  std::cout<<std::endl;

} /* -----  end of constructor  ----- */


/*-----------------------------------------------------------------------------
 *  Main
 *-----------------------------------------------------------------------------*/
int main ()
{
  const unsigned int kVec[3] = { 1, 2, 3 };

  Domain k(3,kVec);

  size_t i = 0;

// direct access works
  for( ; i<3 ; i++)
    std::cout << "Vec direct: " << k.getVec()[i] << std::endl;

  std::cout << std::endl;

// iterator access FAILS for the first element
  std::vector<unsigned int>::const_iterator  it_vec  = k.getVec().begin();

  for ( ; it_vec != k.getVec().end(); it_vec++) 
    std::cout<<"Vec iterator " << (*it_vec) << std::endl;

  return 0;
}       /* ----------  end of function main  ---------- */

使用g++ main.cc -o test编译结果

$ ./test

Iterator in constructor: 1
Iterator in constructor: 2
Iterator in constructor: 3

Vec direct: 1
Vec direct: 2
Vec direct: 3

Vec iterator 140124160
Vec iterator 2
Vec iterator 3

在另一台机器上进行测试:

Vec iterator 0
Vec iterator 0
Vec iterator 3

我通过getVec()错误地返回向量的方式。是个 迭代器处理不正确?我不知道,这里有什么不对或如何解决它。

非常感谢任何帮助,

Da Frenk

3 个答案:

答案 0 :(得分:2)

您正在返回向量的副本而不是引用,因此您无法正确匹配迭代器。您从begin()获得的迭代器来自内部向量的不同副本,而不是您从end()获得的副本

您可以通过将函数原型更改为:

来返回引用,而不是返回内部向量的副本
const std::vector<unsigned int>& getVec() const {return itsVec;}

答案 1 :(得分:1)

您的getVec()方法按值返回向量,这意味着每次调用getVec()时都会获得向量的新副本,因此当您进行迭代时, begin()end()迭代器不兼容。它们属于两种不同的载体。

您可以通过返回对向量的引用来解决此问题:

const std::vector<unsigned int>& getVec() const {return itsVec;}

或扩展您的类以返回向量的开始和结束迭代器。

class Domain
{
 public:
  std::vector<unsigned int>::iterator begin() { return itsVec.begin(); }
  std::vector<unsigned int>::iterator end()  { return itsVec.end(); }
  std::vector<unsigned int>::const_iterator begin() const  { return itsVec.begin(); }
  std::vector<unsigned int>::const_iterator end() const  { return itsVec.end(); }
  std::vector<unsigned int>::const_iterator cbegin() const  { return itsVec.begin(); }
  std::vector<unsigned int>::const_iterator cend() const  { return itsVec.end(); }
 // ... other methods
};

答案 2 :(得分:1)

问题是你正在返回向量的COPY,它会立即被丢弃,留下一个不指向任何地方的迭代器。

您可能希望返回引用或const引用。