在C++中实现 Java 集合层次结构

Implementing Java Collection hierarchy in C++

本文关键字:集合 层次结构 Java 实现 C++      更新时间:2023-10-16
#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;
}

上面的代码中,我想在迭代器类中制作运算符 ++((,虚拟的,以便在 main 中我可以使用:

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

而不必使用:

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

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

虚拟函数只能通过指针调用。begin函数返回的不是指针。如果修复此问题,则会遇到许多与类型转换相关的编译错误。

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

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

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

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

让我先说一下,你的实现不会按你的预期工作。 目前看到的所有其他答案也不会。

使用指针作为多态迭代器的实现注

定要失败,多态迭代器不会改变您必须实现所有多态具体迭代器的事实。

与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 个问题:

  • ptr应该在类中受到保护Iterator而不是私有的,如果您希望能够在派生类的重写方法中访问它
  • 应将增量运算符声明为virtual Iterator<T> ...
  • 如果要将数组迭代到空值,则应在末尾写入空值。

因此,这在没有警告的情况下编译,并且在Clang 3.4.1中运行良好:

#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;
}

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