With
class Node{
template<class T>
friend class DLList;
the only thing that is templated is the friend. Node
is not templated.
Solution: Make Node a template as well
template<class T>
class DLList; // declare DLList is a template so that it's a template when friended
template<class T>
class Node{
friend class DLList<T>; // Node is now a friend of DLList<T> and no other DLLists
private:
T data;
Node* next;
Node* prev;
public:
Node():next(nullptr),prev(nullptr){} // I don't recommend having this constructor.
// If T doesn't have a default constructor,
// the program will not compile and the error
// messages can be quite inscrutable.
Node(T val):data(val), next(nullptr),prev(nullptr){}
// I moved data to the front of the line because
// the members are always initialized in the
// same order as they are defined no matter the
// order they are in in the initializer list. It
// doesn't matter here, but I see it as a
// sanitation issue.
Node(const Node<T>& rhs):data(rhs.val), next(nullptr),prev(nullptr){}
// corrected this constructor to use the correct
// input value. I don't recommend having this
// constructor. 1) You Probably don't need it.
// the default constructor should be good enough
// and 2) this isn't really a copy.
~Node();
};
template<class T>
class DLList // now we define DLList for real.
{
};
But... There is a better way to do this.
We can make the Node
a private member of the DLList
class. Now that only DLList
can see Node
s, we can make all of the Node
members public
.
template<class T>
class DLList
{
private:
class Node{
public:
T data;
Node* next;
Node* prev;
Node(const T & val):data(val), next(nullptr),prev(nullptr){}
Node(const T & val, Node* p, Node* n):data(val), next(p), prev(n){}
// Having a constructor that sets the prev and
// next pointers makes insertion logic just a
// bit easier later.
~Node();
};
// private DLList stuff goes here
public:
// public DLList stuff goes here
};
Why is this a good idea? Encapsulation. No one outside if DLList
should know that Node
even exists. They should certainly never be allowed to get their hands on one. Some idiot could delete
one without properly removing it. They could accidentally mangle it. Don't give them the chance. Give them iterators and give them data. Never give them a Node
.