STL迭代器作为返回值

4

我有一个包含std :: vector的A类,我希望从A类外部访问该向量。

我首先想到的是创建一个get函数,该函数返回指向向量的迭代器,但是要遍历整个向量,我需要两个迭代器(begin和end)。

我想知道是否有一种方法(技术或模式)可以使用一个迭代器遍历整个向量?或者还有其他方法可以访问向量,当然不能使用向量作为返回值:)


4
我希望你能理解,暴露向量迭代器与暴露成员变量(例如向量变量本身)没有任何区别。实际上,这甚至更糟。你可能会暴露私有成员的指针。 - Ajeet Ganga
5个回答

8
为什么不在你的类中添加一个begin()和end()函数,它们只需返回v.begin()和v.end()即可?(假设v是你的向量。)
class MyVectorWrapper
{
public:
  // Give yourself the freedom to change underlying types later on:
  typedef vector<int>::const_iterator const_iterator;

  // Since you only want to read, only provide the const versions of begin/end:
  const_iterator begin() const { return v.begin(); }
  const_iterator end() const { return v.end(); }

private:
  // the underlying vector:
  vector<int> v;
}

然后,您可以像处理其他类一样迭代您的类:
MyVectorWrapper myV;
for (MyVectorWrapper::const_iterator iter = myV.begin(); iter != myV.end(); ++i)
{
  // do something with iter:
}

1

STL引入了使用两个迭代器来描述范围的习语。从那时起,begin()end()就成为了获取器。这样做的优点是可以使用指向C数组的简单指针作为完美的迭代器。缺点是需要携带两个对象。据我所知,C++1x将引入一个范围概念来在某种程度上减轻后者的负担。


1

给予向量这么多的访问权限似乎不明智,但如果你要这样做,为什么不直接返回向量的指针或引用呢?(返回向量本身可能会导致潜在的高昂代价。)或者,可以返回一对 std::pair<> 迭代器。

迭代器只是一个指示器,例如,指针可以是完全良好的随机访问迭代器。它不携带关于对象所在容器的信息。


2
这似乎违反了通常的惯用语,即begin()end()成员可以访问底层容器。 - sbi
1
仅提供迭代器,您不允许更改容器本身(添加/删除元素)。此外,您只能提供const_iterators以进行只读访问。是否这样做是正确的取决于类的作用:也许它只想控制插入/删除的方式? - UncleBens
2
我同意;如果你必须提供对向量的访问,只需返回一个引用。如果您想确保只读访问,请将其设置为const引用。 - Charles Salvia
1
我认为将指针或引用分发给容器本身只会带来不利影响 - OP已经考虑仅提供迭代器,因此似乎他并不想改变容器。那么为什么要提供对它的访问呢? - Georg Fritzsche

0

更多:

template <typename T,typename A = std::allocator<T>>
class yetAnotherVector
{
public:
 typedef std::_Vector_iterator<T, A> iterator;
protected:
 std::vector<T,A> mV;
public:
 void add(const T& t)
 {
  if(!isExist(t))mV.push_back(t);
 }
    bool isExist(const T& t)
 {
  std::vector<T,A>::iterator itr;
  for(itr = mV.begin(); itr != mV.end(); ++itr)
  {
   if((*itr) == t)
   {
    return true;
   }
  }
  return false;
 }
 iterator begin(void){return mV.begin();}
 iterator end(void){return mV.end();}
};

0

听起来像是你需要完成的任务可能会潜在违反所谓的迪米特法则。 这个法则通常是过度设计,但往往遵守它是合理的。尽管您可以通过仅提供const-iterator 来授予只读访问权限,但仍然存在您的迭代器可能会被使无效(在使用向量时很容易)而不为第三方所知的风险。由于您永远无法预测程序随时间的变化,因此最好避免提供可能被误用的功能。
常见格言:让您的类接口易于使用且难以滥用。 第二部分对于整体产品质量至关重要。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接