我正在为自定义容器(一些哈希映射类)编写迭代器类,让我们调用此容器Map
。
由于几个原因,从iterator
派生const_iterator
似乎很方便,我已经在其他一些自定义容器(一个数组类)中做了这个,这很好用,所以我想坚持这种模式。
但现在这导致了以下问题(非常笼统/抽象,我很抱歉):
无论const_iterator
的关键数据成员是什么(可能是Map
引用,还是指向Map::Elements
的指针,都有很多方法可以实现),需要非const ,因此const_iterator
和派生的iterator
都可以在其方法中有意义地使用它。
但是,在处理const Map
对象时(例如调用方法const_iterator Map::Begin( void ) const
),如何以正确的方式初始化这个非常量数据成员?
为了说明我的问题,我编写了一些示例代码,通过使用const_cast来解决问题,我认为这是一种糟糕的风格:
#include <vector>
template< typename K, typename T >
class Map
{
public:
class const_iterator
{
public:
const_iterator( Map const & a_Map, int a_Index ) :
m_Index( a_Index ),
m_Map( const_cast< Map & >( a_Map ) ) // Note the use of const_cast
{
}
private:
Map & m_Map;
int m_Index;
};
class iterator : public const_iterator
{
public:
T & operator * ( void )
{
return m_Map.mElements[ m_Index ];
}
};
public:
const_iterator Begin( void ) const { return const_iterator( *this, 0 ); }
iterator Begin( void ) { return iterator( *this, 0 ); }
private:
std::vector< T > m_Elements;
};
答案 0 :(得分:2)
当我过去玩这个时,我确信继承并不是一个好主意。虽然iterator
和const_iterator
可能会共享大量代码,但它们在界面中并没有太多共享。
相反,我使用模板来重用代码,因此iterator
和const_iterator
只是同一模板的两个版本。提供适当的隐式转换运算符。
但是如果你坚持继承模型,并且不希望你的迭代器有自己的非const引用(即它的构造函数初始化它的非const版本和基类的const版本),那么{{1我想是唯一真正的选择。