实施(重载) - >操作者

时间:2013-11-10 20:48:49

标签: c++ iterator operators

我有哈希表,我用2d向量实现

std::vector<std::vector<std::string> > htable;

另外,我在我的myiterator类中编写了++, - 和*运算符,它是我的hash-table的子类。

class myiterator{
    public:
        myiterator();
        myiterator(std::vector<std::vector<std::string> >& v, int ii, int jj) : 
            vec(v), i(ii), j(jj) {}
        std::string operator*(){
            return vec[i][j];
        }
        myiterator& operator++(){
            if(j==vec[i].size()-1){
                int start=0;
                while(vec[start].size()==0){
                    start++;
                }
                i=start;
                j=0;
            }
            else{
                j++;
            }
            return *this;
        }
        // myiterator operator++(int); // postfix operator
        myiterator& operator--(){
            if(j==0){
                int end=vec[i].size()-1;
                while(vec[end].size()==0){
                    end--;
                }
                i=end;
                j=vec[end].size()-1;
            }
            else{
                j--;
            }
            return *this;
        } // prefix operator
        // myiterator operator--(int); // postfix operator
        std::string* operator->();
    private:
        std::vector<std::vector<std::string> >& vec; // the vector we are iterating over
        int i; // the position in the vector (first dimension)
        int j; // the position in the vector (second dimension)
    };
    myiterator begin() {
        int start=0;
        while(htable[start].size()==0){
            start++;
        }
        return (myiterator(htable, start, 0));
    }
    myiterator end(){
        int end=htable.size()-1;
        while(htable[end].size()==0){
            end--;
        }
        return (myiterator(htable, end, htable[end].size()-1));
    }

问题是,我该如何实施 - &gt;运营商?他做了什么?我用Google搜索,但我不明白。对不起,如果我的问题是nooby和basic。提前谢谢。

3 个答案:

答案 0 :(得分:2)

到目前为止看起来不错。我会说

    std::string* operator->(){
        return &vec[i][j];
    }

关于operator-&gt;的奇怪之处是在调用用户定义的运算符后 - >编译器将调用operator-&gt;再次返回任何内容。所以你的运营商 - &gt;应返回您要访问的对象的地址。

答案 1 :(得分:1)

John已经回答了您关于operator->的问题。我只是想对operator++operator--发表评论。我会发表评论,但这会有点长:)

让我们从这开始:

    myiterator& operator++(){
        if(j==vec[i].size()-1){
            int start=0;
            while(vec[start].size()==0){
                start++;
            }
            i=start;
            j=0;
        }
        else{
            j++;
        }
        return *this;
    }

您有start=0行。这意味着每次到达内部向量(j==vec[i].size()-1)的末尾时,您将从头开始寻找“下一个”向量 - 然后可能会回到您开始的相同向量。 / p>

这是一个相对较小的错误(你应该只设置start=i+1),但请注意你永远不会检查你是否在外部向量的末尾!好吧,你不应该在结束后对迭代器做++,对吗?实际上,你应该能够在结束后到达1个单元格!所以这将是一个问题。您应该检查i==vec.size()是否在某处。

最后 - 除了这两个问题之外,代码看起来都会起作用 - 但它很麻烦。它可以简单得多。怎么样?那么,你有2个不同的案例从一开始就拆分 - 检查是否j==vec[i].size()-1。我看到了逻辑 - 但试着想一下有点不同。在c ++中,它是一个很好用的习惯用法,用来表示“最后一个元素之后”。你会在一秒钟内看到这里的效果如何。但是成语 - 或者“用得好” - 检查你是否在最后的方式是j==vec[i].size()所以当我看到size()-1我立即看到“事情可以更简单”。

另一件事告诉我这可能更简单,就是你在两个不同的地方进行相同的测试:测试当前内部向量中是否有更多元素,这样你就可以移动到下一个元素。您可以在

行中执行此操作
if (j==vec[i].size()-1)

while(vec[start].size()==0)

(你检查当前向量是否为空,意味着它没有剩余元素 - 因为它根本没有元素 - 因此你移动到下一个)

这两件事(检查两次并使用size()-1)告诉我这个功能可以更简单。这是一个例子:

myiterator& operator++(){
  j++; // First I increase j! Why? Because I want to get to "one after end" if it's the end
  while(j==vec[i].size()){ // in "iterator speak" this is equivalent to "(j==i->end())"
    i++;
    if (i==vec.size()) // in "iterator speak" this is "i==vec.end()"
      break;
    j=0; // in "iterator speak" this is "j=i->begin()"
  }
  return *this;
}

这看起来更短更优雅,特别是如果您选择将ij更改为迭代器(意味着您不需要),它可以轻松“看到”内部迭代器保留引用vec!仅ij!)

尝试以这种方式制作operator--,如果你真的想要一个很好的练习来理解迭代器 - 就像我建议ij更改为迭代器本身而不用在所有上都有一个参考vec ,看看你是否可以使它工作:)

答案 2 :(得分:0)

通常应用程序将使用运算符 - &gt;用于返回指向内部对象的指针的智能指针对象。见usage