C++ ->;的实现(重载);操作人员

C++ ->;的实现(重载);操作人员,c++,iterator,operators,C++,Iterator,Operators,我有一个哈希表,我用2d向量实现它 std::vector<std::vector<std::string> > htable; std::vector-htable; 此外,我在myiterator类中编写了++、--和*运算符,myiterator类是哈希表的子类 class myiterator{ public: myiterator(); myiterator(std::vector<std::vector<

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

std::vector<std::vector<std::string> > htable;
std::vector-htable;
此外,我在myiterator类中编写了++、--和*运算符,myiterator类是哈希表的子类

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));
    }
类myiterator{
公众:
myiterator();
myiterator(std::vector&v,int ii,int jj):
vec(v),i(ii),j(jj){}
std::字符串运算符*(){
返回向量[i][j];
}
myiterator&运算符++(){
如果(j==vec[i].size()-1){
int start=0;
while(vec[start].size()=0){
启动++;
}
i=开始;
j=0;
}
否则{
j++;
}
归还*这个;
}
//myiterator运算符++(int);//后缀运算符
My迭代器和运算符--(){
如果(j==0){
int end=vec[i].size()-1;
while(vec[end].size()=0){
结束--;
}
i=结束;
j=vec[end].size()-1;
}
否则{
j--;
}
归还*这个;
}//前缀运算符
//myiterator运算符--(int);//后缀运算符
std::string*运算符->();
私人:
std::vector&vec;//我们正在迭代的向量
int i;//向量中的位置(第一维)
int j;//向量中的位置(第二维)
};
我的迭代器begin(){
int start=0;
while(htable[start].size()=0){
启动++;
}
返回值(myiterator(htable,start,0));
}
myiterator end(){
int end=htable.size()-1;
while(htable[end].size()=0){
结束--;
}
返回(myiterator(htable,end,htable[end].size()-1));
}

问题是,我必须如何实现->操作符?他是干什么的?我用谷歌搜索了一下,但我不明白。对不起,如果我的问题是nooby和basic。提前谢谢。

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

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

运算符->的奇怪之处在于,在调用用户定义的运算符->之后,编译器将再次调用运算符->来处理返回的任何内容。因此,操作员->应该返回您要访问的对象的地址。

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

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

运算符->的奇怪之处在于,在调用用户定义的运算符->之后,编译器将再次调用运算符->来处理返回的任何内容。因此,操作员->应该返回您要访问的对象的地址。

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

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

运算符->的奇怪之处在于,在调用用户定义的运算符->之后,编译器将再次调用运算符->来处理返回的任何内容。因此,操作员->应该返回您要访问的对象的地址。

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

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

运算符->的奇怪之处在于,在调用用户定义的运算符->之后,编译器将再次调用运算符->来处理返回的任何内容。因此,运算符->应该返回要访问的对象的地址。

通常应用程序将运算符->用于返回内部对象指针的智能指针对象。请参见

通常,应用程序将使用操作符->来处理智能指针对象,该对象返回指向内部对象的指针。请参见

通常,应用程序将使用操作符->来处理智能指针对象,该对象返回指向内部对象的指针。请参见

通常,应用程序将使用操作符->来处理智能指针对象,该对象返回指向内部对象的指针。请参见

John已经回答了您关于
操作员->
的问题。我只是想评论一下
操作符+++
操作符--
。我可能会发表评论,但这会有点长:)

让我们从这里开始:

    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
)时,您都会从一开始就开始寻找“下一个”向量,然后可能会直接返回到开始的同一个向量

这是一个相对较小的错误(您应该只设置
start=i+1
),但请注意,您也从不检查是否位于外向量的末尾!嗯,你不应该在结束后在迭代器上执行
++
,对吗?实际上,你应该能在结束后到达1个牢房!所以这是个问题。您应该在某处检查
i==vec.size()

最后,除了这两个问题之外,代码看起来还可以工作,但它很麻烦。它可以简单得多。怎么用?好的,从一开始就有两种不同的情况-检查
j==vec[i].size()-1
。我明白其中的逻辑,但试着换一种方式来思考。在C++中,使用一个很好的习惯用法来“结束最后一个元素”来结束信号。你很快就会看到这里有多好。但是检查你是否在最后的习惯用法是
j==vec[i].size()
,所以当我看到
size()-1
时,我立即看到“事情可以更简单”

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

if (j==vec[i].size()-1)

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

这两件事(检查两次并使用
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;
}
这看起来更短、更优雅,特别是如果您选择将
i
j
更改为迭代器,则可以很容易地“查看”内部迭代器