D
D.C.Dunn
[prescript: I accidentally sent this to comp.std.c++. I hope the
moderators there bounce it. I think it should be posted here.]
Please forgive the naivety of my following question. I'm new to C++,
and am trying to get to grips with OOP. My question concerns iterators
and derived classes. Please note that I don't want to use the STL, just
get my head round how to do this from scratch.
I have (at least) two classes derived from an abstract base class, and
I want to use templates. The derived classes are doubly linked lists
and are either circular or terminating.
I have defined an abstract base class with a nested iterator.
template <class T>
struct CSnode
{
sometype<T> stuff;
CSnode *pPrev;
CSnode *pNext;
// constructor etc..
};
template <class T>
class CScontour
{
public:
class iterator
{
private:
CSnode<T> *current;
public:
friend class CScontour; // let CScontour methods access current.
// define operators ++, --, ==, etc.
};
virtual bool empty() = 0;
virtual void insert(iterator, data<T>);
// etc
};
Now, I want to derive the following classes:
template <class T>
class circular : public class CScontour
{
private:
CSnode<T> *pTail;
public:
bool empty() {return pTail == 0;}
void insert(.... , data<T>);
}
template <class T>
class terminating : public class CScontour
{
private:
CSnode<T> *pTail;
CSnode<T> *pHead;
public:
bool empty() {return pHead == 0;}
void insert(...., data<T>);
}
---------------------
In place of .... my naive attempt was to put
CScontour<T>::iterator it
(and then typename CScontour<T>::iterator it when g++ complained about
it). This gives a compiler error that it.current is private. I (think?)
that I don't want to make the derived classes friend classes of
CScontour<T>::iterator, otherwise any new derived classes would require
changing the abstract base class definition. It seems very wrong to
make the abstract base class know a priori what all of its derived
classes will be.
Other alternatives that I've tried:
a) to define the iterator class external to the CScontour class, which
seem inelegant. It also suffers that unless I make the derived classes
friends then it.current is always private.
b) to define the nested iterator class as a base class and derive
template<class T>
class circular::iterator : CScontour<T>::iterator
{
// etc.
};
This gives me trouble in that there are no longer matching function
declarations of insert() etc, so that the derived classes become
abstract classes and any attempt to instantiate objects of those
classes fails.
Of course ultimately I want a container of CScontour's, some circular,
some terminating. I will need to iterate over the container, so I need
to be able to declare "CScontour<T>::iterator it" which will 'do the
right thing' on each of the derived classes.
Please can someone point me in the direction of the/an answer. RTFM
replies welcome, with a reference to the correct FM
Best wishes,
David
moderators there bounce it. I think it should be posted here.]
Please forgive the naivety of my following question. I'm new to C++,
and am trying to get to grips with OOP. My question concerns iterators
and derived classes. Please note that I don't want to use the STL, just
get my head round how to do this from scratch.
I have (at least) two classes derived from an abstract base class, and
I want to use templates. The derived classes are doubly linked lists
and are either circular or terminating.
I have defined an abstract base class with a nested iterator.
template <class T>
struct CSnode
{
sometype<T> stuff;
CSnode *pPrev;
CSnode *pNext;
// constructor etc..
};
template <class T>
class CScontour
{
public:
class iterator
{
private:
CSnode<T> *current;
public:
friend class CScontour; // let CScontour methods access current.
// define operators ++, --, ==, etc.
};
virtual bool empty() = 0;
virtual void insert(iterator, data<T>);
// etc
};
Now, I want to derive the following classes:
template <class T>
class circular : public class CScontour
{
private:
CSnode<T> *pTail;
public:
bool empty() {return pTail == 0;}
void insert(.... , data<T>);
}
template <class T>
class terminating : public class CScontour
{
private:
CSnode<T> *pTail;
CSnode<T> *pHead;
public:
bool empty() {return pHead == 0;}
void insert(...., data<T>);
}
---------------------
In place of .... my naive attempt was to put
CScontour<T>::iterator it
(and then typename CScontour<T>::iterator it when g++ complained about
it). This gives a compiler error that it.current is private. I (think?)
that I don't want to make the derived classes friend classes of
CScontour<T>::iterator, otherwise any new derived classes would require
changing the abstract base class definition. It seems very wrong to
make the abstract base class know a priori what all of its derived
classes will be.
Other alternatives that I've tried:
a) to define the iterator class external to the CScontour class, which
seem inelegant. It also suffers that unless I make the derived classes
friends then it.current is always private.
b) to define the nested iterator class as a base class and derive
template<class T>
class circular::iterator : CScontour<T>::iterator
{
// etc.
};
This gives me trouble in that there are no longer matching function
declarations of insert() etc, so that the derived classes become
abstract classes and any attempt to instantiate objects of those
classes fails.
Of course ultimately I want a container of CScontour's, some circular,
some terminating. I will need to iterate over the container, so I need
to be able to declare "CScontour<T>::iterator it" which will 'do the
right thing' on each of the derived classes.
Please can someone point me in the direction of the/an answer. RTFM
replies welcome, with a reference to the correct FM
Best wishes,
David