Hello all,
I am trying to make a linked list (class-based). I'm not sure if I went actually did it right. I get a compiler error on the segment of code that deals with printing the linked list to stdout. Here is the seqment in question.

// print contents of list
void Node::printAll() const
{
	Node *temp = NULL;
	temp = this;
	if (temp->previous != NULL)
		temp = findFirst(temp);
	else
	{
		do
		{
			// prints all items except last
			// since it tests for next to point to NULL
			cout << temp->first << " " << temp->last << endl;
			if (temp->next == NULL)
				continue;
			else
				temp = temp->next;
		} while (temp->next != NULL);
	}
	// print last item
	cout << temp->first << " " << temp->last << endl;
}

The error my compiler displays is
"cannot convert from const Node *const to Node* Conversion loses qualifiers". I'm not sure how to fix this.

And here is the whole thing for reference.

#ifndef NODE_H
#define NODE_H
#include <string>
using std::string;

class Node
{
public:
	Node();
	Node* addToFront(Node*);
	Node* addToBack(Node*);
	Node* findFirst(Node*) const;
	Node* findLast(Node*) const;
	void printAll() const;
private:
	Node *previous, *next;
	string first, last;
	void collectData(Node*);
};
#endif
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
#include <string>
using std::string;

#include "Node.h"

Node::Node() : previous(NULL), next(NULL)
{
	collectData(this);
}

// add new Node to beginning
Node* Node::addToFront(Node *n)
{
	Node *temp = new Node;
	n = findFirst(n);
	temp->next = n;
	n->previous = temp;
	return temp;
}

// add new Node to end
Node* Node::addToBack(Node *n)
{
	Node *temp = new Node;
	n = findLast(n);
	//point new object to what was last object
	temp->previous = n;
	// point what was last object to new last object
	n->next = temp;
	return temp;
}

// returns first item in list
Node* Node::findFirst(Node *n) const
{
	// find 1st item in list
	if (n->previous != NULL)
	{
		while (n->previous != NULL)
			// point to previous object
			n = n->previous;
	}
	return n;
}

// returns last item in list
Node* Node::findLast(Node *n) const
{
	// find last item
	if (n->next != NULL)
	{
		while (n->next != NULL)
			// point to next Node object
			n = n->next;
	}
	return n;
}

// print contents of list
void Node::printAll() const
{
	Node *temp = NULL;
	temp = this;
	if (temp->previous != NULL)
		temp = findFirst(temp);
	else
	{
		do
		{
			// prints all items except last
			// since it tests for next to point to NULL
			cout << temp->first << " " << temp->last << endl;
			if (temp->next == NULL)
				continue;
			else
				temp = temp->next;
		} while (temp->next != NULL);
	}
	// print last item
	cout << temp->first << " " << temp->last << endl;
}

// helper function; adds data to object
void Node::collectData(Node *n)
{
	string first, last;
	cout << "Enter first name:" << endl;
	cin >> first;
	n->first = first;
	cout << "Enter last name:" << endl;
	cin >> last;
	n->last = last;
}
#include <iostream>
using std::cout;
using std::endl;
using std::cin;
#include "Node.h"

int main()
{
	Node *me = new Node();
	me->addToBack(me);
	me->printAll();
	me->printAll();
	return 0;
}

Recommended Answers

All 11 Replies

Your function is a bit, no way too complicated >_>, just keep one pointer to track the first link of your list and reference it when you want to print it.

Node *list, *front, *temp;
list = new struct node;
front = list

//your code here, do not modify "front"


list = front;               //print from begining
while(list != NULL) 
cout<<list->data;
list = list->next;

I'm a little confused on your reply.
You have a pointer-to-Node to track the beginning of the list but the beginning can change throughout the code. What was the first object may not always be the first object. That's why I have it find the first object and start from there. Then on lines 10-12 of your code you show a while-loop to print all the objects, but it wont print the last object as it is typed. On the last Node, list->next will point to NULL so the while condition test fails and moves on without printing the last object.

What my question really was about is how do I convert a const Node *const to Node*? The this pointer is type const Node *const. I apologize if I wasn't clear from the start.

Your function is a bit, no way too complicated >_>, just keep one pointer to track the first link of your list and reference it when you want to print it.

Node *list, *front, *temp;
list = new struct node;
front = list

//your code here, do not modify "front"


list = front;               //print from begining
while(list != NULL) 
cout<<list->data;
list = list->next;

As far as i can tell, this only a single link list, besides you can just redefine front everytime there is a new first link, it saves you alot of effort later on, and you will print EVERY element in the list because it isn't list->next, it is list that has to equal NULL. Lastly, a plain void function works just fine. Unless you are required to use a const, I would suggest you refrain from doing so, no need to make it harder than it actually is :)

Hmm. I thought having two pointers, one to the previous node and one to the next node qualified this as a doubly-linked list. I could be wrong.

From the header file

private:	Node *previous, *next;	string first, last;

Also, thank you for your help.

"cannot convert from const Node *const to Node* Conversion loses qualifiers". I'm not sure how to fix this.

You can use const_cast, i.e.

Node * temp = const_cast<Node*>(this);

Maybe you could revise the 'constness' of the code (I did not look too closely). Perhaps read about Const correctness.

OH I see what you were doing, thought you were using a structure, not class lol, thought you made two single links >_<.

Declare const Node* temp in const member functions - that's all. These functions must not modify Node fields but you can modify them via Node* temp pointer.

Yet another remark:
Did you want to implement Linked List class? If so why did you implement Node only class? A list is not a simple Node. Now you are trying to manipulate with list via Node pointers only in C (not C++ ) style. It's an example of a bad class design...

Yes, I've been reading that FAQ site. I got the idea from that site that if you create a function that *should not* modify the members it deals with you can/should declare it const. I also read that the const_cast is not preferred or dangerous? I'm just trying to learn the proper way to do this and since this is not a school project, I'm being a little picky about it. I appreciate your help. I will probably give up and make is simpler in the end anyway.

You can use const_cast, i.e.

Node * temp = const_cast<Node*>(this);

Maybe you could revise the 'constness' of the code (I did not look too closely). Perhaps read about Const correctness.

Interesting. I was mistakenly under the impression that a Linked list is just collection of nodes. Could you show me how I should be going about this? If you don't mind. I keep googling "linked list" and I only find examples using structs. Then I decided to go about it in a class, just to practice and whatnot. Thanks for your help.

Declare const Node* temp in const member functions - that's all. These functions must not modify Node fields but you can modify them via Node* temp pointer.

Yet another remark:
Did you want to implement Linked List class? If so why did you implement Node only class? A list is not a simple Node. Now you are trying to manipulate with list via Node pointers only in C (not C++ ) style. It's an example of a bad class design...

A type (a class) is a set of values + a set of operations. Strictly speaking, a (linked) list is not a simple collection of nodes. It's a collection of values (data) with operators:
- first (or head, or front)
- last (or tail, or back)
- count (or size)
- append (or add, or push_back)
- insert (optional)
- erase
- clear
- next
- prev (optional)
- find
- swap (optional)
- sort (optional)
and so on...

Look at http://en.wikipedia.org/wiki/Linked_lists.
Read about STL list container as an example of true class list.

As usually, a list implementation is a chained (by pointers) collection of nodes. A list node is a term for a value plus internal (as usually, invisible for list users) reference field(s) data structure.

Of course, you may define specialized class list of public nodes with exposed auxiliary next/prev fields. Remember: class list user don't want to take much trouble over these pointer fields. Moreover, it a very dangerous approach (how about unpredictable change of reference fields by wrong user code? ). It's class list member functions job.

Oh okay. Thank you ArkM that does help.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.