【问题标题】:STL iterator as return valueSTL 迭代器作为返回值
【发布时间】:2010-12-19 15:53:53
【问题描述】:

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

我首先想到的是创建一个将迭代器返回到向量的 get 函数,但是遍历向量我需要两个迭代器(开始和结束)。

我想知道是否有任何方法(技术或模式)仅使用一个迭代器来迭代整个向量?或者也许是其他方式来访问向量,当然不使用向量作为返回值:)

【问题讨论】:

  • 我希望你明白暴露一个向量的迭代器与暴露一个成员变量没有什么不同? (例如向量变量本身)实际上更糟。您可能正在公开指向私有成员的指针。

标签: c++ stl iterator


【解决方案1】:

STL 引入了使用两个迭代器来描述范围的习惯用法。从那时起,begin()end() 就是吸气剂。这样做的好处是一对指向 C 数组的简单指针可以用作完美的迭代器。缺点是需要随身携带两个物品。 AFAIK,C++1x 将引入一个范围概念以在一定程度上缓解后者。

【讨论】:

    【解决方案2】:

    更多:

    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();}
    };
    

    【讨论】:

      【解决方案3】:

      为什么不在你的类中添加一个 begin() 和 end() 函数,只需要 return v.begin();return 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:
      }
      

      【讨论】:

        【解决方案4】:

        听起来你需要完成的是可能违反所谓的Law of Demeter。这条法律通常是矫枉过正,但通常遵守它是合理的。尽管您可以通过仅给出 const-iterators 来授予只读访问权限,但您仍然面临在第三方不知情的情况下,您的迭代器将失效(很容易使用向量)的风险。由于您永远无法预测您的程序将如何随着时间的推移而发展,因此最好避免提供可能被滥用的功能。
        共同座右铭:让您的课堂界面易于使用且不易误用。第二部分对整体产品质量很重要。

        【讨论】:

          【解决方案5】:

          给向量提供如此多的访问权限似乎是不明智的,但是如果您要这样做,为什么不只返回一个指针或对向量的引用呢? (返回向量本身可能会很昂贵。)或者,返回一个 std::pair&lt;&gt; 的迭代器。

          迭代器只是一个对象的指示器;例如,指针可以是非常好的随机访问迭代器。它不携带有关对象所在容器类型的信息。

          【讨论】:

          • 这似乎与要求 begin()end() 成员访问底层容器的常见习语背道而驰。
          • 通过只给出迭代器,您不允许更改容器本身(添加/删除元素)。此外,您只能提供const_iterators 进行只读访问。这是否是正确的做法取决于类的作用:也许它只想控制插入/擦除的发生方式?
          • 我同意;如果您必须提供对向量的访问,只需返回一个引用。如果您想确保只读访问,请将其设为 const 引用。
          • 我只看到分发指向容器本身的指针或引用的缺点 - OP 已经考虑只提供迭代器,因此他似乎不想更改容器。那为什么要提供访问权限呢?
          猜你喜欢
          • 1970-01-01
          • 2021-12-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-21
          • 1970-01-01
          • 2021-02-17
          相关资源
          最近更新 更多