面向对象的迭代std :: vector的方法?

时间:2010-10-12 01:28:15

标签: c++ oop vector

我有一个具有子控件指针的std :: vector的类。出于显而易见的原因,我不希望类的用户直接访问std :: vector。我想要的只是给调用者提供指针的方法。什么是一个很好的OO方式来做到这一点? (经常调用此函数)

由于

3 个答案:

答案 0 :(得分:14)

提供一个向矢量返回const_iterator的函数。添加一个以将迭代器返回到向量的末尾也很有用。

class MyClass {
public:
  typedef vector<T>::const_iterator c_iter;

  c_iter getBegin() const {return v.begin();}
  c_iter getEnd() const {return v.end();}

  // and perhaps if it's useful and not too invasive.
  const T& getAt(int i) const {return v.at(i);}

  //stuff
  vector<T> v;
};

答案 1 :(得分:3)

迭代器是一种很好的,明显的方法。访问者模式是让客户端代码能够对向量中的每个元素进行操作的另一种方式:在某些方面,它甚至更清晰,对用户的暴露更少,并允许容器更多控制,例如:

  • 客户端没有问题,可能会在以后失效的迭代器
  • 获取互斥锁,直到客户端代码在允许其他线程在容器上运行之前读取所有条目
  • 如果过滤或合成元素,则无需创建复杂的迭代器代理对象

BUT

  • 客户端更强烈地锁定您提供的任何迭代:例如您通常可以通过容器执行多个独立迭代器,从而促进对多个元素的操作,但访问者通常在返回之前运行一次:任何额外的功能 - 暂停/恢复迭代,删除元素 - 需要由容器的访问代码特别支持(也许是来自访问者功能的返回码)。 (即使没有明确的支持,也可以通过异常来终止迭代)。相比之下,使用迭代器,可以在迭代器上使用单个擦除函数,无论是begin(),是否递增,以及find()等其他操作:这是一个更清晰的功能因素。 / LI>

这看起来像是:

class Container
{
  public:
    template <typename Visitor>
    void visit(Visitor& visitor)
    {
        for (Vector::const_iterator i = v_.begin(); i != v_.end(); ++i)
             visitor(*i);
    }

  private:
    typedef std::vector<X> Vector;
    Vector v_;
};

// client code...

struct Visitor
{
    void operator()(const X&) { ... }
    // any data you want to update as you iterate...
};

Visitor v(...any construction arguments...);
container.visit(v);

答案 2 :(得分:1)

我通常会这样做:

class MyClass {
public:   
  const unsigned int GetNumberOfItems() { return v.size(); }

  T* GetItemNumber(const unsigned int n) 
  {
    // 3 options here, thrown your own exception type, or use the std one, or
    // or just return NULL meaning nothing there or out of range.
    try{
      return v.at(n);
    } catch (std::out_of_range &e){
    }

    return NULL;    
  }

  vector<T> v;
};

然后你可以做类似的事情:

MyClass cl;
int count = cl.GetNumberOfItems();
for (int i = 0; i < cl.GetNumberOfItems(); i++){
  T* item = cl.GetItemNumber(i);
}

不需要外部世界的迭代器。如果您必须将此类内容暴露给标准C API,那么它很容易公开。