I'm trying to implement a linked list in C++, but every time I compile, I get an error that says 'Node* Node::nextPtr' is private. If I change nextPtr to have public protection, then I don't get the error and my list is fine. Can someone tell me why this is and how to fix it? My list and node classes are as follows:
//list.h
#include <string>
#include "node.h"
using namespace std;
class List
{
public:
List();
bool isEmpty();
void insertAtFront(string Word);
void displayList();
private:
Node * firstPtr;
Node * lastPtr;
};
//node.h
#ifndef NODE_H
#define NODE_H
#include <string>
using namespace std;
class Node
{
public:
Node(string arg);
string getData();
private:
string data;
Node * nextPtr;
};
//node.cpp
#include <iostream>
#include <string>
#include "node.h"
using namespace std;
Node::Node(string arg)
:nextPtr(0)
{
cout << "Node constructor is called" << endl;
data = arg;
}
string Node::getData()
{
return data;
}
//list.cpp
#include <iostream>
#include "list.h"
#include "node.h"
using namespace std;
List::List()
:firstPtr(0), lastPtr(0)
{
}
bool List::isEmpty()
{
if(firstPtr == lastPtr)
return true;
else
return false;
}
void List::displayList()
{
Node * currPtr = firstPtr;
do
{
if(currPtr->nextPtr == lastPtr) // Error here
cout << endl << currPtr->getData() << endl;
cout << endl << currPtr->getData() << endl;
currPtr = currPtr->nextPtr; //Error here
}
while(currPtr != lastPtr);
}
void List::insertAtFront(string Word)
{
Node * newPtr = new Node(Word);
if(this->isEmpty() == true)
{
firstPtr = newPtr;
cout << "Adding first element...." << endl;
}
else if(this->isEmpty() == false)
{
newPtr->nextPtr = firstPtr; //Error here
firstPtr = newPtr;
cout << "Adding another element...." << endl;
}
}
You didn't show the definitions of your member functions inside the List class, but I bet it is due to those member functions try to access nextPtr from the Node class. You can,
make nextPtr public from Node
add public accessor functions to Node to access it
declare List as a friend from Node, friend class List;
Because somewhere in your code, you access Node * nextPtr by non member functions of class Node. You can create a getter for nextPrt to avoid that.
Related
So I was doing a linked list assignment where given two numbers in a linked list form, add the numbers up and make the final answer in a linked list form. I keep getting an "undeclared identifier" error for my code and I was wondering how to fix it.
Error message:
List.cpp:48:3: error: use of undeclared identifier 'append'
append(h, c);
Thanks.
#include <iostream>
#ifndef LISTNODE_H
#define LISTNODE_H
using namespace std;
class ListNode {
public:
ListNode();
ListNode(int value, ListNode* next);
int value;
ListNode *next;
private:
friend class List;
};
#endif
#include <iostream>
#include "ListNode.h"
using namespace std;
ListNode:: ListNode() {
value = 'b';
next = NULL;
}
#include <iostream>
#include "ListNode.h"
#include <vector>
#ifndef LIST_H
#define LIST_H
using namespace std;
class List {
public:
List();
void append(ListNode* node, vector<char> c);
ListNode *head;
};
#endif
#include <iostream>
#include <string>
#include "List.h"
#include <vector>
#include "ListNode.h"
using namespace std;
void List:: append(ListNode *node, vector<char> c) {
//ListNode *temp
for(int i = 0; i < c.size(); i++) {
if(head == NULL) {
head = node;
}
else {
ListNode* itr = head;
while(itr -> next != NULL) {
itr = itr -> next;
}
node = itr -> next;
node -> value = c[i];
cout << node -> value << endl;
}
}
}
List:: List() { //Initializes the head and the tail for the whole class
head = NULL;
}
int main() {
ListNode *h;
string num1, num2, sentence;
vector<char> c;
cout << "Type in two numbers" << endl;
cout << "Number 1: " << endl;
cin >> num1;
cout << "Number 2: " << endl;
cin >> num2;
//cout << "Type in a sentence: " << endl;
//cin >> sentence;
cout << "--------" << endl;
for(int i = 0; i < num1.size(); i++) {
c.push_back(num1[i]);
}
append(h, c);
return 0;
}
This code:
append(h, c);
calls a free function named append. But there is no such function in your code.
You do have an append function inside the List class, but that's a member function, so you need a List object to call that function on. So you'll need something like:
List l;
l.append(h, c);
You defined the member function append in the class List (that (the function) by the way does not make any sense)
void List:: append(ListNode *node, vector<char> c) {
//...
}
But inside main you are calling a stand-alone function append
append(h, c);
that is not related to the class List.
You even did nit declare in main an object of the type List.
Pay attention to that the class ListNode has the data member of the type int.
int value;
However you are trying to save in this data member objects of the type char that are element of a vector declared like vector<char> c.
And it is totally unclear why the default constructor of the class ListNode initializes the data member value with the character 'b'.
ListNode:: ListNode() {
value = 'b';
next = NULL;
}
So the code in whole does not make sense.
It seems that you mean that the data member value of the class ListNode had the type char instead of int.
char value;
In this case the function append of the class List can be declared and defined the following way
void List:: append( const std::vector<char> &v )
{
ListNode **current = &head;
while ( *current ) current = &( *current )->next;
for ( const auto &item : v )
{
*current = new ListNode( item, nullptr );
current = &( *current )->next;
}
}
To learn implementation of binary search tree,
I created a class bst and am facing problem in its add_node_private function.
bst.cpp -
#include <iostream>
#include <cstdlib>
using namespace std;
#include "bst.h"
// bst constructor
bst::bst() {
root = nullptr;
}
// methods of binary search tree
bst::node* bst::create_leaf(int a) { // creating a leaf with key
node* leaf = new node;
leaf->key = a;
leaf->left = nullptr;
leaf->right = nullptr;
return leaf;
}
// adding a leaf to the tree
void bst::add_leaf(int k) {
bst::add_leaf_private(k, root); // just calls the private function
// providing it with root
}
void bst::add_leaf_private(int k, node* ptr) {
if (ptr == nullptr) {
ptr = create_leaf(k);
cout << k << " added\n";
return;
}
if (k > ptr->key) {
cout << "went left of " << ptr->key << endl;
add_leaf_private(k, ptr->right);
}
if (k < ptr->key) {
cout << "went right of " << ptr->key << endl;
add_leaf_private(k, ptr->left);
}
if (k == ptr->key) {
cout << "key " << k << " already exists\n";
}
}
bst.h
#ifndef _BST_H
#define _BST_H
class bst
{
private:
struct node{
int key;
node* left;
node* right;
};
//private methods
void add_leaf_private(int k,node* ptr);
//void print_private(node* ptr);
public:
node* root=nullptr;
//bst constructor
bst();
//public methods
node* create_leaf(int k);
void add_leaf(int k);
//void print();
};
#endif // _BST_H
When I add leaves, I output shows that they were added (like this- 5 added)
main.cpp
#include <iostream>
#include <cstdlib>
#include "bst.h"
using namespace std;
int main(){
bst b1;
int tree_keys[]{50,70,21,4,32,64,15,51,14,100,83,2,3,70,87,90};
for(int x: tree_keys){
b1.add_leaf(x);
}
cout<<"root"<<b1.root<<endl;
return 0;
}
But I don't see any statement went left of ... or went right of ... which I was expecting. And later I checked and found out even after adding a bunch of nodes, I have my root==nullptr and I don't know where the nodes were being added then?
you are never updating root. Its always nullptr
you need
void bst::add_leaf_private(int k, node* ptr) {
if (ptr == nullptr) {
ptr = create_leaf(k);
root = ptr;
cout << k << " added\n";
return;
}
I made a stupid mistake of using ptr in the function add_leaf_private by value. I should have passed it by reference as I intend to change it in the function. Replacing ptr with &ptr solved the problem.
So I'm working on a college project where I need to create a linked list of 'Structures'. and when I'm adding a new element to the linked list I get this error, which is weird because I am not even using the stack while doing it.
Here's how 'Structure' is defined:
#ifndef Structure_h
#define Structure_h
#include <stack>
using namespace std;
class Structure
{
public:
int Integer;
stack <int> s;
};
#endif
Definition of node:
#pragma once
#ifndef Node_h
#define Node_h
using namespace std;
#include "Structure.h"
class Node
{
public:
Node();
Structure Str;
Node *next;
};
#endif
LinkedList.h:
#pragma once
#ifndef LinkedList_h
#define LinkedList_h
using namespace std;
#include "Node.h"
class LinkedList
{
public:
LinkedList();
int size;
void add(int a);
Node *Current;
Node *Start;
};
#endif
LinkedList.cpp:
#include "LinkedList.h"
#include <iostream>
LinkedList::LinkedList()
{
Node FirstNode;
Start = Current = &FirstNode;
cout << "Start = " << Start->Str.Integer << endl;
cout << "Current = " << Current->Str.Integer << endl;
}
void LinkedList::add(int a)
{
Node n;
n.Str.Integer = a;
Current->next = &n;
Current = Current->next;
cout << Current->Str.Integer;
}
Now whenever I create a new LinkedList and adding something to it I get this error.
I got a feeling like I'm using the Stack wrong somehow, not sure why though.
Thank you from advance.
In this method:
void LinkedList::add(int a)
{
Node n;
n.Str.Integer = a;
Current->next = &n;
Current = Current->next;
cout << Current->Str.Integer;
}
you are adding as next local variable n, it will get destroyed once add returns. This is undefined behaviour. You should use Node* n = new Node;, dont forget to deallocate.
[edit]
The same applies to other places in your code where you take a pointer to local variable and store it as a list node.
You have:
void LinkedList::add(int a)
{
Node n;
n.Str.Integer = a;
Current->next = &n;
// Here, you are storing a pointer to a local variable.
// The pointer becomes a dangling pointer when the function returns.
Current = Current->next;
cout << Current->Str.Integer;
}
Use a dynamically allocated Node.
void LinkedList::add(int a)
{
Node* n = new Node;
n->Str.Integer = a;
Current->next = n;
Current = Current->next;
cout << Current->Str.Integer;
}
I have created a linked list that each node holds a CarPart object. I know that the issue is that I am not properly de-referencing the pointer and it just displays the pointer and not the actual value... problem being is I have not been able to figure out how properly display the car part items to the console.
Per request I have removed any code that does not effect the outcome of what I am trying to do.
Main.cpp
#include "stdafx.h"
#include "List.h"
int main()
{
/*cout << new Node(new CarPart("Hello", "World", 99.00));*/
List partsList;
partsList.push_front(new CarPart("FL2016", "Oil Filter", 18.95));
partsList.push_front(new CarPart("RS12YC", "Spark Plug", 4.15));
partsList.push_front(new CarPart("D5941", "Digital Tire Guage", 12.15));
partsList.push_back(new CarPart("G19216", "Car Wash Solution", 8.15));
partsList.display();
cout << "now we are going to remove the first item in the list" << endl;
system("PAUSE");
partsList.pop_front();
partsList.display();
system("PAUSE");
cout << "now we are going to remove the LAST item from the list" << endl;
partsList.pop_back();
partsList.display();
system("PAUSE");
return 0;
}
List.h
#pragma once
#include "node.h"
class List
{
private:
int listSize;
Node* n;
Node* temp;
Node* head;
Node* tail;
public:
List();
void push_front(CarPart*);
void push_back(CarPart*);
void pop_front();
void pop_back();
void display();
~List();
};
List.cpp
#include "stdafx.h"
#include "List.h"
List::List()
{
}
void List::display()
{
Node* test = head;
for (int i = 0; i < listSize; i++) {
cout << test;
}
}
Node.h
#pragma once
#include "CarPart.h"
class Node
{
private:
CarPart* data;
Node* next;
Node* previous;
public:
Node();
CarPart* getData();
void setData(CarPart*);
void setNext(Node*);
void setPrevious(Node*);
Node* getPrevious();
Node* getNext();
void display();
~Node();
};
Node.cpp
#include "stdafx.h"
#include "Node.h"
Node::Node()
{
}
void Node::display()
{
cout << data;
}
CarPart.h
#pragma once
#include <iostream>
#include <string>
using namespace std;
class CarPart
{
private:
string partNumber;
string description;
double price;
public:
CarPart();
CarPart(string, string, double);
string getPartNumber();
string getDescription();
double getPrice();
void display();
~CarPart();
friend ostream& operator<<(ostream& os, CarPart* dt);
};
CarPart.cpp
#include "stdafx.h"
#include "CarPart.h"
CarPart::CarPart()
{
}
CarPart::CarPart(string n, string d, double p)
{
partNumber = n;
description = d;
price = p;
}
string CarPart::getPartNumber()
{
return partNumber;
}
string CarPart::getDescription()
{
return description;
}
double CarPart::getPrice()
{
return price;
}
ostream& operator<<(ostream& os, CarPart* dt)
{
os << dt->getPartNumber() << endl << dt->getDescription() << endl << dt->getPrice() << endl;
return os;
}
There are multiple problems with your code, but they all share the same root problem, so I'll just explain the first one, and after figuring out how to fix it you should be able to fix the rest of them by yourself:
void List::display()
{
Node* test = head;
for (int i = 0; i < listSize; i++) {
cout << test;
}
}
As you've observed, all this does is print the value of the pointer. Examining the contents of your header files, it appears that your class Node has a method called display().
You did now show the display() method, but given what I see in List::display(), it's reasonable to expect that Node::display()'s purpose would be similar, so you probably meant to do this, instead:
void List::display()
{
Node* test = head;
for (int i = 0; i < listSize; i++) {
test->display();
}
}
But this is not right, either. All this will accomplish is invoke your head Node's display() method over and over again. If your List has five Nodes, you'll get the contents of the first Node display()ed five times. You simply need to change this loop to walk through the link list, instead.
Now, your Node::display() method has the same problem as above, but now you should be able to fix it yourself.
I'm trying to create a program that reads from a text file and stores the words into a singly linked list. I'm supposed to create my own linked list as opposed to using the STL. I've tried looking up a fair number of tutorials, but I keep getting an error on the variable "head." It says "a value type of Node cannot be used to initialize an entity of type Node"
This is List.cpp:
#include "List.h"
#include "Node.h"
#include <iostream>
using namespace std;
void List::add(string s){
Node* newNode = new Node();
newNode->addString(s);
newNode->setNext(NULL);
Node *temp = head;
if(temp != NULL)
{
while(temp->Next() != NULL)
{
temp = temp->Next();
}
temp->setNext(newNode);
}
else
{
head = newNode;
}
}
void List::print(){
Node *temp = head;
if(temp == NULL)
{
cout<<"EMPTY"<< endl;
return;
}
if(temp->Next() == NULL)
{
cout<<temp->Word();
cout<< "-->";
cout<< "NULL" << endl;
}
else
{ do{
cout<<temp->Word();
cout<<"-->";
temp = temp->Next();
}
while( temp != NULL);
cout << "NULL" << endl;
}
}
void List::read(ifstream& fin){
while(!fin.eof())
{
fin>>sTemp;
add(sTemp);
}
}
This is Node.h
using namespace std;
#include <string>
class Node
{ string val;
Node* next;
public:
Node(void){}
Node(string s)
{
val = s;
next = nullptr;
}
void addString(string aString){ val = aString;};
void setNext(Node* aNext){next = aNext;};
string Word(){return val;};
Node* Next(){return next;};
string sTemp;
};
This is List.h
#include <string>
#include <fstream>
#include "Node.h"
using namespace std;
class List{
Node* head;
public:
List()
{
head = NULL;
}
void print();
void add(string s);
void find(string key);
void read(ifstream& fin);
string sTemp;
}
Under the actual List.cpp, it gives me an error when I say Node *temp = head; with the aforementioned error. Any reason why and how can I fix this?
Part of the problem here is that in List.cpp you've included Node.h twice.
directly includes List.h which itself includes Node.h
directly includes Node.h
I'm surprised that the compiler didn't warn you about this. It seems instead that it chose to redefine Node hence you end up with two Node values which aren't compatible. You need to add include guards to your header files to prevent double includes
List.h
#if !LIST_H
#define LIST_H
...
#endif
Node.h
#if !NODE_H
#define NODE_H
...
#endif
Also note that it's generally speaking considered bad practice to have using statements in header files. Instead use namespace qualified names in headers and put the using statements into the .cpp files.