我实现了一个简单的类MyClass
,里面有一个分配有new
的数组(我知道我可以使用STL容器,但我试图了解它们是如何工作的) 。我还创建了一个迭代器子类,能够迭代MyClass
对象的所有元素:
class MyIterator : public iterator<forward_iterator_tag,int>
{
private:
int* data= nullptr;
int length;
int pointer=0;
int nullvalue=0;
public:
MyIterator(int* data, int length, bool end= false)
{
this->data= data;
this->length= length;
if(end)
pointer=-1;
}
~MyIterator()
{
delete[] data;
}
MyIterator& operator++()
{
if(pointer!= length-1)
{
pointer++;
}
else
{
pointer= -1;
}
return *this;
}
bool operator==(const MyIterator& other)
{
return pointer==other.pointer;
}
bool operator!=(const MyIterator& other)
{
return pointer!= other.pointer;
}
int& operator* ()
{
if(pointer==-1)
return nullvalue;
else
return data[pointer];
}
};
class MyClass
{
private:
int* data= nullptr;
int length= 100;
public:
MyClass()
{
data= new int[length];
for(int i=0; i<length;i++)
data[i]=i+1;
}
iterator<forward_iterator_tag,int> begin()
{
return MyIterator(data,length);
}
iterator<forward_iterator_tag,int> end()
{
return MyIterator(data,length,true);
}
};
如果我以这种方式使用它,迭代器就可以工作:
for(MyIterator i= MyClass_instance.begin(); i!=MyClass_instance.end();i++) {...}
如果我尝试将其与BOOST_FOREACH一起使用,它无效:
BOOST_FOREACH(int i, MyClass_instance) {...}
这些是我得到的错误:
答案 0 :(得分:3)
您正在通过将值{/ 1>} 按值 返回来切片迭代器。你不能这样做。
通过引用返回可以避免切片问题但是引入了一个更糟糕的问题:它返回对临时¹的引用。
因此,请按值返回实际迭代器类型来修复它。
您的类型缺少const迭代器。
所有迭代器成员都不是const-correct。
此外,根据页面 Extensibility ,您似乎需要添加
std::iterator<>
您的迭代器类型(What is The Rule of Three?)的“三次规则”实现存在严重问题。
每次迭代器不存在时,您都会删除容器的数据。 namespace boost {
template<> struct range_mutable_iterator<MyClass> {
typedef MyClass::MyIterator type;
};
template<> struct range_const_iterator<MyClass> {
typedef MyClass::MyConstIterator type;
};
}
本身永远不会释放数据......
修复上述的大部分(?):
<强> Live On Coliru 强>
MyClass
¹(除非你将迭代器存储在其他地方,但由于许多原因,这将是一个巨大的反模式)