我有哈希表,我用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。提前谢谢。
答案 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;
}
这看起来更短更优雅,特别是如果您选择将i
和j
更改为迭代器(意味着您不需要),它可以轻松“看到”内部迭代器保留引用vec
!仅i
和j
!)
尝试以这种方式制作operator--
,如果你真的想要一个很好的练习来理解迭代器 - 就像我建议i
和j
更改为迭代器本身而不用在所有上都有一个参考vec
,看看你是否可以使它工作:)
答案 2 :(得分:0)
通常应用程序将使用运算符 - &gt;用于返回指向内部对象的指针的智能指针对象。见usage