在C++中实现 Java 集合层次结构
Implementing Java Collection hierarchy in C++
#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 ++
的覆盖版本,它也可以正常工作。
- 如何重构类层次结构以避免菱形问题
- C++ 中模板化类型的类层次结构
- 为什么不同类型层次结构的指针之间的dynamic_cast定义得很好?
- 继承层次结构并将元素添加到向量
- C++ 类层次结构中的"对齐"是什么意思?
- 相同的层次结构,访问基类的受保护成员时的行为不同
- 类层次结构中的运算符重载
- 如何在层次结构中实现运算符使用?
- 反向层次结构中的可变参数模板参数
- 如何在继承层次结构中调用具有默认参数的构造函数?
- C++ 提升 - 包含类层次结构对象的类的序列化
- 在C++继承层次结构时提取实现者
- 在C++中将类实例添加到对象层次结构中的问题
- 确定大层次结构中基本指针的实际类型,无需dynamic_cast
- 在继承层次结构中复制和移动
- 模板冲突的类型-但类型应该是相同的cfr类层次结构
- 删除父/子窗口层次结构的最佳方法
- 是否可以使一个类成为两个不同层次结构的子类?
- 我们可以在层次结构中创建多个纯虚拟接口及其实现而不会代码爆炸吗?
- 在C++中实现 Java 集合层次结构