具有派生类的自定义容器的迭代器

时间:2010-02-03 11:42:49

标签: c++ inheritance iterator

我有一个自定义容器,它以两种不同的方式实现,但只有一个接口。有点像这样。

    class Vector 
    {
       virtual Iterator begin() = 0;
       virtual Iterator end () = 0 ;

    ... // some more functions.
    } ;

    class VectorImplA : public Vector
    {
       Iterator begin() { return m_data.begin() ; }
       Iterator end () { return m_data.end() ; }
    private:
       SomeFloatContainer m_data ;
    } ;

    class VectorImplB : public Vector
    {
       Iterator begin() { return m_data.end() ; }
       Iterator end() ; { return m_data.end() ; }


    private:
        std::vector <float> m_data ;

    } ;

我需要的是Iterator的统一接口,以便我可以在基类中使用它。任何想法?

3 个答案:

答案 0 :(得分:7)

我之前遇到过这个问题。虽然有很多方法可以解决您的问题,但您很可能应该放弃向量基类的想法。您可能应该做的是模仿c ++ STL容器的设计方式。

STL由 concepts 而不是基类组成。 std::vectorContainer概念的模型,但不从Container基类继承。概念是概念的任何模型应遵守的一组要求。有关Container的要求,请参阅this页面。

Container状态的要求,例如,您应该将容器内容的类型设置为value_type,并将解析迭代器设置为iteratorconst_iterator。此外,您应该定义返回迭代器的begin()end()函数,依此类推。

然后,您需要更改在Vector基类上运行的函数,而不是对符合概念强加的要求的任何类进行操作。这可以通过模板化函数来完成。你不一定要坚持使用STL所使用的概念,你也可以自己做饭。坚持STL中定义的概念具有STL算法(例如std::sort)可以对您的容器进行操作的额外好处。

快速举例:

class VectorImplA
{
public:
    typedef VectorImplAIterator iterator;

    iterator begin();
    iterator end();
};

class VectorImplB
{
public:
    typedef VectorImplBIterator iterator;

    iterator begin();
    iterator end();
};

template <typename VectorConcept>
void doSomeOperations(VectorConcept &container)
{
    VectorConcept::iterator it;
    it = container.begin();
}

int main()
{
    VectorImplA vecA;
    VectorImplB vecB;
    doSomeOperations(vecA); // Compiles!
    doSomeOperations(vecB); // Compiles as well!
}

作为奖励,要回答原始问题,请考虑以下设计(我不会这样做!):

struct IteratorBase
{
    virtual void next() = 0;
};

struct IteratorA : IteratorBase
{
    void next() {};
};

struct IteratorB : IteratorBase
{
    void next() {};
};

class Iterator
{
    IteratorBase *d_base;
public:
    void next() { d_base->next(); }
};

答案 1 :(得分:0)

可能的方法是使用模板类作为容器,私有数据容器作为参数。这样,迭代器可以在类中独立于数据容器定义 我只是不确定这是否足够“统一”以满足你的需要。

答案 2 :(得分:0)

我之前遇到过同样的问题。我在定义迭代器类

时略微修改了解决方案#2
class Iterator :public boost::iterator_facade<Iterator,element_type, forward_traversal_tag>
{
  ...
}

这样我就可以在容器中使用STL算法了。