我有任务写自己的容器Linked_list和Array_list.我有一个接口:
typedef int value_type;
class Container
{
public:
class Iterator
{
public:
Iterator();
Iterator(value_type* other);
Iterator(const Iterator& other);
Iterator& operator=(const Iterator& other);
...
};
Container();
Container(const Container& other);
~Container();
virtual value_type& front() const=0;
virtual value_type& back() const=0;
virtual Iterator begin() const=0; //
...
};
我做派生类Linked_list和Array_list:
class Linked_list:public Container
{
public:
long int cur_size;
List elem;
static Link end_;
class Iterator: public Container::Iterator
{
friend Linked_list;
Link *p;
};
Iterator begin() const; //overriding virtual function return type differs ...
...
}
我认为这是错的.应该嵌套类Linked_list :: Iterator是派生类吗?
是否可以这样做,如果我不能更改界面?
解决方法
考虑到您不能使用模板的设计约束,而不是一件事情应该改变:添加接口IteratorImpl.因此,您可以使类Iterator从基类Container非虚拟.它需要是非虚拟的,因为STL相似的迭代器应该具有值语义.参见
pimpl idiom了解更多细节如何工作!
喜欢这个:
typedef int value_type;
class Container
{
protected:
class IteratorImpl
{
public:
virtual void next() = 0;
virtual IteratorImpl* clone() const = 0;
virtual value_type get() const = 0;
virtual bool isEqual(const IteratorImpl& other) const = 0;
};
public:
class Iterator
{
public:
Iterator(IteratorImpl* impl) : impl(impl) {}
~Iterator() { delete impl; }
Iterator(const Iterator& other) : impl(other.impl->clone()) {}
Iterator& operator=(const Iterator& other) {
IteratorImpl* oldImpl = impl;
impl = other.impl->clone();
delete oldImpl;
}
bool operator == (const Iterator& other) const
{
return impl->isEqual(*other->impl);
}
Iterator& operator ++ ()
{
impl->next();
return *this;
}
value_type& operator*() const
{
return impl->get();
}
value_type* operator->() const
{
return &impl->get();
}
};
Container();
Container(const Container& other);
~Container();
virtual value_type& front() const=0;
virtual value_type& back() const=0;
virtual Iterator begin() const=0; //
...
};
然后在你的派生只是实现IteratorImpl:
class Linked_list:public Container
{
protected:
class IteratorImpl: public Container::IteratorImpl
{
....
};
public:
Iterator begin() const { return new IteratorImpl(firstNode); }
Iterator end() const { return new IteratorImpl(nodeAfterLastNode); }
...
};
这些firstNode和nodeAfterLastNode只是我的猜测 – 使用任何你需要实现IteratorImpl接口…