I'm studying C++ container and iterators and I'm trying to implement a rudimental linked list, just to get the hang of thi inner workings of iterators and container related stuff.
I defined a node class, along with a list class and the associated iterator, every class in its own header file,and each header is implemented in a separated code file.I didn't care about friend declarations,that was something I intended to cater to while trying to compile the project, but I stumbled upon something I failed to understand.
I defined several private fields in each class,and I expected the compiler to throw some errors at me during compilation, but it seems to be just fine with that! can you explain where am I wrong?? here's the code:
the node class:
template <typename T>
class mylist_node {
public:
mylist_node(const T&,mylist_node<T>*);
~mylist_node() {}
private:
T element;
mylist_node<T> *next;
};
the list class:
template <typename T>
class mylist {
public:
typedef mylist_iterator<T> iterator;
mylist() : head(NULL),tail(NULL) {}
void push_back(const T&);
bool empty();
iterator begin();
iterator end();
private:
mylist_node<T> *head,*tail;
};
the list implementation code:
#include <cstdlib>
#include "mylist_node.h"
#include "mylist_iterator.h"
#include "mylist.h"
template <typename T>
void mylist<T>::push_back(const T& element)
{
//dynamically allocated object so it is not destroyed on function exit
mylist_node<T> *new_node=new mylist_node<T>(element,NULL);
if (head==NULL)
head=new_node;
else
tail->next=new_node;
tail=new_node;
}
template <typename T>
bool mylist<T>::empty()
{
return head==tail;
}
template <typename T>
typename mylist<T>::iterator mylist<T>::begin()
{
return mylist_iterator<T>(head);
}
template <typename T>
typename mylist<T>::iterator mylist<T>::end()
{
return mylist_iterator<T>(NULL);
}
and the iterator class:
template <typename T>
class mylist_iterator {
public:
T &operator*();
const mylist_iterator<T> &operator++();
bool operator!=(const mylist_iterator<T>&);
private:
mylist_iterator(mylist_node<T> *pointee) : pointee(pointee) {}
mylist_node<T> *pointee;
};
obiouvsly the mylist<T>::push_back()
and the overloaded operators in mylist_iterator
all access the private fields in mylist_node
.
I separatedly compile the source files without the compiler complaining about anything at all!
There must be something I didn't fully understand..
thanks!