带有派生类的自定义容器的迭代器 [英] Iterator for custom container with derived classes

查看:143
本文介绍了带有派生类的自定义容器的迭代器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

... //一些更多的功能。
};

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

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


private:
std :: vector< float> m_data;

};

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

解决方案

我自己之前遇到了这个问题。虽然有办法解决你的问题,你很可能应该放弃一个向量基类的想法。你可能应该做的是模仿c ++ STL容器的设计方式。



STL由概念组成,而不是基类。 std :: vector Container 概念的模型,但不会继承 Container 基类。概念是该概念的任何模型应遵守的一组要求。有关容器此页面c $ c>例如



Container 的要求,例如你应该typedef容器的内容为 value_type ,typedef迭代器为 iterator const_iterator 。此外,您应该定义 begin() end()函数返回迭代器,

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



快速示例:

  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); //编译!
doSomeOperations(vecB); //编译好!
}

为了回答原来的问题,请考虑以下设计不会这样走!):

  struct IteratorBase 
{
virtual void next = 0;
};

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

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

类迭代器
{
IteratorBase * d_base;
public:
void next(){d_base-> next(); }
};


I've a custom container which is implemented in two different ways, but with a single interface. some thing like this.

    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 ;

    } ;

What I need is a unified interface to Iterator, so that I'can use it in base class. Any Ideas ?

解决方案

I've run into exactly this problem myself before. While there are ways to solve your problem, you most likely should let go of the idea of a vector base class. What you probably should do instead, is mimic the way the c++ STL container are designed.

The STL consists of concepts rather than base classes. An std::vector is a model of the Container concept, but does not inherit from a Container base class. A concept is a set of requirements that any model of the concept should adhere to. See this page for the requirements for Container for example.

The requirements for Container state for example that you should typedef the type of the contents of the container as value_type, and typedef iterators as iterator and const_iterator. Furthermore, you should define begin() and end() functions returning iterators, and so on.

You'll then need to change functions that operate on your Vector base class to instead operate on any class that adheres to the requirements imposed by the concept. This can be done by making the functions templated. You don't necessarily have to stick to the concepts used by the STL, you might as well cook up your own. Sticking to the concepts as they are defined in the STL has the additional benefit that the STL algorithms (std::sort for example) can operate on your containers.

Quick example:

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!
}

As a bonus, to answer the original question, consider the following design (I wouldn't go this way though!):

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(); }
};

这篇关于带有派生类的自定义容器的迭代器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆