As suggested by Some programmer dude, make NodeList a friend of Node. When class A declares class B to be a friend, B can see and interact with the private members of A. Note that the reverse is not true. friendship is one way. A cannot see the private members of B unless B declares A to be a friend.
This one change will solve all of the problems asked in the question.
The rest of this code dump is to make writing a linked list a little easier for you. Linked lists are best considered a rite of passage for programmers. You'll find you rarely use them in real life programming, but they serve as a notorious weeder of CS students. Practically no one gets them right the first time or two. They require a moderate amount of care and attention to book keeping. Pen and paper step-by-step drawings of the list and the interactions you wish to perform on the list are highly recommended to help visualize and debug a linked list.
You may also find delving into pointers to pointers extremely helpful. For example, see the Alternative Using Pointer To Pointer section of this linked answer.
Comments embedded where needed.
#include <iostream>
class Node
{
friend class NodeList; // NodeList, and no one else, can now see the private
// members of Node
public:
// Node must be given a value and it not given a next, it's automatically NULL
// this makes it almost impossible to not point link at something useful,
// eliminating the most common of the trivial linked list bugs
Node(int value, Node * link = nullptr);
~Node(); //if it doesn't do anything. Get rid of it. See the Rule of Zero
private:
//next pointer
Node * next;
int data;
};
class NodeList
{
public:
NodeList();
~NodeList();
//this should delete the whole list
void delList(Node * head);
private:
//head
Node * head;
};
Node::Node(int value, Node * link) : next(link), data(value)
{
// test code
std::cout << "Node data = " << data << " next = " << next << '\n';
}
Node::~Node()
{
// test code
std::cout << "~Node data = " << data << '\n';
}
NodeList::NodeList()
{
// test code to give delList something to delete
head = new Node(1,new Node(2,new Node(3)));
}
NodeList::~NodeList()
{
delList(head);
}
//this is the nodestructkindathing
void NodeList::delList(Node * head) // watch out! Parameter head shadows member head!
{
// Warning: This function is recursive and a potential stack-killer if given a
// long list. Prefer iteration here unless given a reason to do otherwise
// and guarantees on maximum list length
if (!head)
return;
delList(head->next);
delete head;
}
int main()
{
NodeList test;
}
Expected output:
Node data = 3 next = 0
Node data = 2 next = 0x2ec6cc0
Node data = 1 next = 0x2ec6ce0
~Node data = 3
~Node data = 2
~Node data = 1
A discussion of the Rules of Three, Five and Zero. Understanding these rules is a must if you want a stable linked list or to program non-trivial systems in C++.
Documentation on friend.