在C ++中实现Java Collection层次结构

时间:2017-05-11 06:37:31

标签: java c++ stl

#include <iostream>
using namespace std;

template <typename T> class Iterator
{

T * ptr;

public: 

    Iterator(T * addr)
    {
        ptr=NULL;
        ptr=addr;
    }

    //not working
    //virtual Iterator * operator ++(int x);


    /*Iterator * operator ++(int x)
    {
        (this->ptr)++;
        return this;
    }*/

    T operator *()
    {
        return *ptr;
    }
};

template<typename T>
class Vector{

T * a;
public:
    Vector(size_t n)
    {
        a=new T[5];
    }
    T& operator [](int x)
    {
        return a[x];
    }
    class iterator: public Iterator<T>
    {
        public:

            iterator(T * addr): Iterator<T>(addr)
            {}

            /* not working 
            Iterator<T> * operator ++(int x)
            {
                Iterator<T>::ptr++;
                return this;
            }*/


            //working now
            iterator * operator ++(int x)
            {
                Iterator<T>::ptr++;
                return this;
            }
    };
    iterator begin()
    {
        iterator ob(&a[0]);
        return ob;
    }
};

int main()
{

Vector <char> v(5);

for(int i=0;i<5;i++)
    v[i]=i+65;

for(int i=0;i<5;i++)
    cout<<v[i]<<endl;

/*~~~~~~ What I want~~~~~~

Iterator <char> p=v.begin();    

*/

// what is working now:

Vector<char>:: iterator p=v.begin();

while(*p){
    cout<<*p<<endl;
    p++;
   }

   return 0;
}

在上面的代码中,我想在Iterator类中创建operator ++(),虚拟,以便在main中我可以使用:

Iterator <char> ptr=v.begin();

而不是必须使用:

Vector <char>:: iterator p=v.begin();

这是一个带有运行时多态性的基类引用,用于确定调用哪个++运算符,具体取决于值是向量还是列表。但是,当我在Iterator类中将其声明为虚拟时,它无效。我必须专门为内部类声明它,但我想要一个像Java一样的单一接口。我试图在c ++中实现java集合层次结构以获得更好的结构。出了什么问题? 是不是因为Iterator是一个模板类,它使得返回类型Iterator也是模板,也就是说,operator ++()函数是一个模板函数?我知道模板函数不能是虚拟的,只有具体的函数才能是虚拟的。可以做些什么来解决这个问题?

4 个答案:

答案 0 :(得分:0)

只能通过指针调用虚函数。您的begin函数不返回指针。如果你修复了那么你会得到很多与类型转换相关的编译错误。

您也可以使用引用,但它应该是r值引用:

Iterator<char> &&p = v.begin();

答案 1 :(得分:0)

以下是具有正确后缀增量版本的示例实现:

template<typename T> 

class Iterator
{
    private: 
    T* ptr;
    public:
    Iterator(T* ptr1):ptr(ptr1)
    {
    }
    virtual Iterator  operator ++(int)
    {
        Iterator result(*this);
        (this->ptr)++;
        return result;
    }
    T operator*()
    {
        return *ptr;
    }
};

template<typename T>
class Vector
{
    private:
    T* data;
    public:
    Vector()
    {
        data = new T(100);
        for(int i=0;i<100;i++)
         data[i]=i;
    }


Iterator<T> begin()
{
    return Iterator<T>(&(data[0]));
}
};

答案 2 :(得分:0)

让我先说一下,你的实施不会像你想象的那样有效。目前看不到所有其他答案。

使用指针作为多态迭代器的实现注定要失败,但是,multiorhphsm并没有改变你必须实现所有具有多态性的具体迭代器这一事实。

与Java类似(我会假设有些熟悉),通过接口可以实现全局多态Iterator。现在C ++没有专用接口,而是我们所拥有的纯虚拟类。

template<typename T>
class Iterator
{
public:
    virtual Iterator& operator++() = 0; // pure virtual
    // other methods
};

template<typename T>
class Vector
{
    class Iterator  // Vector's concrete Iterator
      : public ::Iterator<T>  // analogous to implements in Java
    {
    public:
        Iterator& operator++() override { /* implementation */ }
        // other methods...
    };
};

template<typename T>
class List
{
    class Iterator  // List's concrete Iterator
      : public ::Iterator<T>  // implements
    {
    public:
        Iterator& operator++() override { /* implementation */ }
        // other methods...
    };
};

由于多态性仅适用于引用和指针,因此需要明确编写C ++中的引用

Vector<int> v;
List<int> l;
Iterator<int>&& rit = v.begin();
const Iterator<int>& crit = l.begin();

是你如何使用Iterator

作为最后一点,多态性是一种工具,滥用它比没有它更糟糕。请考虑性能损失并权衡其提供的灵活性。

答案 3 :(得分:-1)

您的代码几乎可以正常运行。我只需修复3个问题:

    如果您希望能够在派生类的重写方法中访问
  • ptr,那么
  • Iterator应该在virtual Iterator<T> ...类中保护而不是私有
  • 递增运算符应声明为#include <iostream> using namespace std; template <typename T> class Iterator { protected: T * ptr; public: Iterator(T * addr) { ptr=NULL; ptr=addr; } //not working - in fact works perfectly virtual Iterator<T> * operator ++(int x) { (this->ptr)++; return this; } T operator *() { return *ptr; } }; template<typename T> class Vector{ T * a; public: Vector(size_t n) { a=new T[5]; } T& operator [](int x) { return a[x]; } class iterator: public Iterator<T> { public: iterator(T * addr): Iterator<T>(addr) {} /* not working Iterator<T> * operator ++(int x) { Iterator<T>::ptr++; return this; }*/ //working now but useless as we can use the base class version /*iterator * operator ++(int x) { Iterator<T>::ptr++; return this; }*/ }; iterator begin() { iterator ob(&a[0]); return ob; } }; int main() { Vector <char> v(5); for(int i=0;i<5;i++) v[i]=i+65; for(int i=0;i<5;i++) cout<<v[i]<<endl; v[5] = 0; // set a null at the end of the vector /*~~~~~~ What I want~~~~~~ and that works...*/ Iterator <char> p=v.begin(); // what is working now: //Vector<char>:: iterator p=v.begin(); while(*p){ cout<<*p<<endl; p++; } return 0; }
  • 如果要将数组迭代到空值,则应在结尾处写入空值。

所以这个编译没有警告,并且与Clang 3.4.1一起正常运行:

operator ++

您可以在Vector类中取消注释{{1}}的覆盖版本,它也可以正常工作。