I have the task to write own containers Linked_list
and Array_list
. I have one interface for them:
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; //
...
};
I did derived classes Linked_list and 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 ...
...
}
I thinks it's all wrong. should nested class Linked_list::Iterator
be a derived class?
Is it possible to do this, if I can't change the interface?
It does not matter whether your class is abstract or concrete, as long as the nested class is either public , protected or the subclass is in the same package and the inner class is package private (default access modifier), the subclass will have access to it.
If a class is nested in the public section of a class, it is visible outside the surrounding class. If it is nested in the protected section it is visible in derived classes, if it is nested in the private section, it is only visible for the members of the outer class.
A class derived from an abstract base class will also be abstract unless you override each pure virtual function in the derived class. The compiler will not allow the declaration of object d because D2 is an abstract class; it inherited the pure virtual function f() from AB .
In C#, a user is allowed to define a class within another class. Such types of classes are known as nested class.
Taking into account your design constraints that you cannot use templates, than one thing should change: add interface IteratorImpl
. Thus you can make class Iterator
from base class Container
non virtual. It needs to be non-virtual since STL-alike iterators should have value semantics. See pimpl idiom for more details how it works!
Like this:
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; //
...
};
Then in your derived just implement 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); }
...
};
These firstNode and nodeAfterLastNode are just my guess - use whatever you need to implement the IteratorImpl interface...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With