C++ 自定义迭代器 class
C++ Custom iterator class
我想实现一个自定义迭代器 class,它与典型的迭代器有一些不同。这个例子中的容器是一个向量,想法是 walk throw 它但是使用特定的语法,像这样:
int main()
{
VectorElement E;
for (size_t i = 0; i < 5; i++)
{
Element e;
e.id = i;
E.push_back(e);
}
for (ElementIterator e(E); e.end(); ++e)
cout << "Element " << e.id << endl;
}
我尝试使用以下定义,但在两次迭代后它在 static_cast 行给了我一个分段错误。有人知道如何改进吗?谢谢
class Element
{
public:
Element() {};
size_t id;
};
typedef vector<Element> VectorElement;
class ElementIterator: public Element
{
typedef vector<Element>::iterator iter;
public:
ElementIterator(const Element& e) : Element(e) { }
ElementIterator(VectorElement& ve_)
{
ve = &ve_;
it = ve->begin();
}
ElementIterator operator++()
{
++it;
*this = static_cast<ElementIterator>(*it);
return *this;
}
bool end()
{
if (it != ve->end() )
return true;
return false;
}
vector<Element>* ve;
iter it;
};
我怀疑发生段错误是因为 'ElementIterator::operator++()' 增加了内部 'it' 属性,然后在没有首先验证其有效性的情况下引用它。可以这样实现:
ElementIterator::operator ++()
{
++it;
if (!this->end())
*this = static_cast<ElementIterator>(*it);
return *this;
}
我终于使用了这个变通方法,它虽然不优雅但有效。主要问题是迭代器 "it" 被覆盖了,所以我把它放在全局范围内。
class Element
{
public:
Element() {};
size_t id;
};
typedef vector<Element> VectorElement;
typedef vector<Element>::iterator iter;
iter it;
class ElementIterator: public Element
{
public:
ElementIterator(const Element& e) : Element(e) { }
ElementIterator(VectorElement& ve_)
{
ve = &ve_;
it = ve->begin();
}
ElementIterator operator++()
{
++it;
*this = static_cast<ElementIterator>(*it);
return *this;
}
bool end()
{
if (it != ve->end() )
return true;
return false;
}
vector<Element>* ve;
};
这是不依赖于全局变量或从 'Element' 派生的替代实现:
class Element
{
public:
Element() {};
size_t id;
};
class ElementIterator
{
std::vector<Element>& ve;
std::vector<Element>::iterator it;
public:
ElementIterator(std::vector<Element>& ve_) : ve(ve_)
{
it = ve.begin();
}
ElementIterator(const ElementIterator &rhs) : ve(rhs.ve)
{
it = rhs.it;
}
ElementIterator operator++()
{
++it;
return *this;
}
const Element *operator ->() const
{
assert(!this->end());
return &(*it);
}
bool end() const
{
if (it == ve.end())
return true;
return false;
}
};
主要:
int main()
{
std::vector<Element> E;
for (size_t i = 0; i < 5; i++)
{
Element e;
e.id = i;
E.push_back(e);
}
for (ElementIterator e(E); !e.end(); ++e)
std::cout << "Element " << e->id << std::endl;
}
注意:我更改了 'ElementIterator::end' 的行为,使其 returns 'true' 在末尾时看起来更合乎逻辑。
在这里试试:
我想实现一个自定义迭代器 class,它与典型的迭代器有一些不同。这个例子中的容器是一个向量,想法是 walk throw 它但是使用特定的语法,像这样:
int main()
{
VectorElement E;
for (size_t i = 0; i < 5; i++)
{
Element e;
e.id = i;
E.push_back(e);
}
for (ElementIterator e(E); e.end(); ++e)
cout << "Element " << e.id << endl;
}
我尝试使用以下定义,但在两次迭代后它在 static_cast 行给了我一个分段错误。有人知道如何改进吗?谢谢
class Element
{
public:
Element() {};
size_t id;
};
typedef vector<Element> VectorElement;
class ElementIterator: public Element
{
typedef vector<Element>::iterator iter;
public:
ElementIterator(const Element& e) : Element(e) { }
ElementIterator(VectorElement& ve_)
{
ve = &ve_;
it = ve->begin();
}
ElementIterator operator++()
{
++it;
*this = static_cast<ElementIterator>(*it);
return *this;
}
bool end()
{
if (it != ve->end() )
return true;
return false;
}
vector<Element>* ve;
iter it;
};
我怀疑发生段错误是因为 'ElementIterator::operator++()' 增加了内部 'it' 属性,然后在没有首先验证其有效性的情况下引用它。可以这样实现:
ElementIterator::operator ++()
{
++it;
if (!this->end())
*this = static_cast<ElementIterator>(*it);
return *this;
}
我终于使用了这个变通方法,它虽然不优雅但有效。主要问题是迭代器 "it" 被覆盖了,所以我把它放在全局范围内。
class Element
{
public:
Element() {};
size_t id;
};
typedef vector<Element> VectorElement;
typedef vector<Element>::iterator iter;
iter it;
class ElementIterator: public Element
{
public:
ElementIterator(const Element& e) : Element(e) { }
ElementIterator(VectorElement& ve_)
{
ve = &ve_;
it = ve->begin();
}
ElementIterator operator++()
{
++it;
*this = static_cast<ElementIterator>(*it);
return *this;
}
bool end()
{
if (it != ve->end() )
return true;
return false;
}
vector<Element>* ve;
};
这是不依赖于全局变量或从 'Element' 派生的替代实现:
class Element
{
public:
Element() {};
size_t id;
};
class ElementIterator
{
std::vector<Element>& ve;
std::vector<Element>::iterator it;
public:
ElementIterator(std::vector<Element>& ve_) : ve(ve_)
{
it = ve.begin();
}
ElementIterator(const ElementIterator &rhs) : ve(rhs.ve)
{
it = rhs.it;
}
ElementIterator operator++()
{
++it;
return *this;
}
const Element *operator ->() const
{
assert(!this->end());
return &(*it);
}
bool end() const
{
if (it == ve.end())
return true;
return false;
}
};
主要:
int main()
{
std::vector<Element> E;
for (size_t i = 0; i < 5; i++)
{
Element e;
e.id = i;
E.push_back(e);
}
for (ElementIterator e(E); !e.end(); ++e)
std::cout << "Element " << e->id << std::endl;
}
注意:我更改了 'ElementIterator::end' 的行为,使其 returns 'true' 在末尾时看起来更合乎逻辑。
在这里试试: