i am simply creating a payroll system that has a employee name and a working hours for that employee.. the data is supposed to be stored in a linked list data structure, but i can not connect the linked list to the object of the class employee, i tried making the pay roll linked list (i.e empList) as a static member so that all the objects of the class can use the same list object and data can be stored but once i compile my code i get an error of "undefined reference to employee::empList" at line 130 that is the last line of constructor, same error on line 150 that is a print pay roll function.. where ever i am trying to call any payRollLinkedList class's function in employee class it gives error.. bottom line is that all i want is to data be stored in a doubly linked list of employees and i can not access the list.
#include <iostream>
using namespace std;
class payRollLinkedList;
class node
{
private:
node* previousPointer;
string name;
int hoursWorked;
node* nextPointer;
friend class payRollLinkedList;
public:
explicit node(const string argName, const int argHoursWorked)
: previousPointer{nullptr}, name{argName}, hoursWorked{argHoursWorked}, nextPointer{nullptr}
{}
};
class payRollLinkedList
{
private:
node* headPointer{nullptr};
node* tailPointer{nullptr};
node* getNewNode(const string argName, const int argHoursWorked)
{
return new node(argName, argHoursWorked);
}
public:
void addAtBack(const string argName, const int argHoursWorked)
{
node* newNode{getNewNode(argName, argHoursWorked)};
if(isEmpty())
{
headPointer = tailPointer = *newNode;
}
else
{
tailPointer->nextPointer = newNode;
newNode->previousPointer = tailPointer;
tailPointer = newNode;
newNode = nullptr;
delete newNode;
}
}
bool deleteNode(string argName)
{
node* currentPointer{headPointer};
if(isEmpty())
{
cout <<"the list is already empty\n";
return false;
}
else
{
while(currentPointer != nullptr)
{
if(currentPointer->name == argName)
{
if(currentPointer == headPointer)
{
node* tempPointer{headPointer};
headPointer = headPointer->nextPointer;
tempPointer->nextPointer = nullptr;
headPointer->previousPointer = nullptr;
delete tempPointer;
break;
}
if(currentPointer == tailPointer)
{
node*tempPointer{tailPointer};
tailPointer = tailPointer->previousPointer;
tempPointer->previousPointer = nullptr;
tailPointer->nextPointer = nullptr;
delete tempPointer;
break;
}
node* tempPointer{currentPointer};
node* nextPtr{tempPointer->nextPointer};
currentPointer = currentPointer->previousPointer;
currentPointer->nextPointer = nextPtr;
nextPtr->previousPointer = currentPointer;
tempPointer->nextPointer = nullptr;
tempPointer->previousPointer = nullptr;
currentPointer = nullptr;
nextPtr = nullptr;
delete tempPointer;
delete currentPointer;
delete nextPtr;
}
else
currentPointer = currentPointer->nextPointer;
}
return true;
}
}
void print()
{
if(isEmpty())
{
cout <<"nothing to show\n";
return;
}
else
{
node* currentPointer{headPointer};
while(currentPointer != nullptr)
{
cout <<currentPointer->name <<"\t";
currentPointer = currentPointer->nextPointer;
}
}
}
bool isEmpty()
{
return headPointer == nullptr? true : false;
}
};
class employee
{
private:
string name;
int hoursWorked;
static payRollLinkedList empList;
public:
employee()
: name{""}, hoursWorked{0}
{}
employee(string argName, int argHoursWorked)
{
name = argName;
hoursWorked = argHoursWorked;
empList.addAtBack(name, hoursWorked);
}
void printPayRoll()
{
empList.print();
}
};
int main()
{
employee emp("usman", 12);
employee emp1("ali", 12);
emp.printPayRoll();
}
https://en.cppreference.com/w/cpp/language/static
You need to define static member of class at global scope (out of class).
i suggest you to split your code .h and .cpp files and define the member in .cpp file.
payRollLinkedList employee::empList;
Related
This question already has an answer here:
Deleting the whole Linked List
(1 answer)
Closed 5 months ago.
I have my linked list code:
#include <string>
#include <iostream>
using namespace std;
class Node
{
public:
string name;
int age;
Node *next;
Node(string name, int age)
{
this->name = name;
this->age = age;
this->next = nullptr;
}
};
class List
{
private:
Node *head;
int size;
public:
List()
{
this->head = nullptr;
this->size = 0;
}
void insert(string name, int age)
{
Node *nodenew = new Node(name, age);
nodenew->next = nullptr;
if (this->head == nullptr)
{
this->head = nodenew;
}
else
{
Node *auxi = this->head;
while (auxi->next != nullptr)
{
auxi = auxi->next;
}
auxi->next = nodenew;
}
this->size = this->size + 1;
}
void print()
{
if (this->head == nullptr)
{
cout << "List is empty"<<endl;
}
Node *auxi = this->head;
cout<<to_string(this->size)+" users in the linked list"<<endl;
while (auxi != nullptr)
{
cout << auxi->name << ", " << auxi->age << endl;
auxi = auxi->next;
}
}
};
int main()
{
List linkedList;
linkedList.insert("David", 56);
linkedList.insert("Susan", 25);
linkedList.insert("Kim", 41);
linkedList.insert("Charles", 23);
linkedList.insert("Bob", 20);
linkedList.insert("James", 75);
linkedList.insert("Carl", 36);
linkedList.insert("Andy", 78);
linkedList.print();
return 0;
}
As you can see I did insert method, print method. And now want I want is to delete all nodes in the linkedList object, so I would like to know if there is some way to make for example something like linkedList = nullptr or something similar to delete all data in my linked list.
I tried to make that in the main method:
linkedList = nullptr;
But my compiler shows me this error:
no operator "=" matches these operands
I hope you can help me, thanks.
linkedList = nullptr; won't work, since it makes no sense. linkedList isn't a pointer. It has a pointer inside of it, but it's not itself a pointer. Besides, if that did work, it wouldn't delete the nodes, so it would be a memory leak.
You should create a function empty() (or more usually called clear()) in your List class. Make it so it deletes all the nodes, then sets head to nullptr and size to 0. Then in main(), you can call linkedList.empty(); (or linkedList.clear();)
I have to make a list using OOP in c++. It is supposed to have functions add, append, display, find, clear and delete.
I have succeeded with all functions except delete. The error is
for prev->getnext()* : "Lvalue required as left operand of assignment"
The classes:
class student
{
private:
string name;
string faculty;
student *next;
public:
student()
{
next = NULL;
}
student(string n, string f)
{
next = NULL;
name = n;
faculty = f;
}
void setname(string n)
{
name = n;
}
void setfac(string f)
{
faculty = f;
}
void setnext(student* stn)
{
next = stn;
}
student*getnext()
{
return next;
}
string getname()
{
return name;
}
string getfac()
{
return faculty;
}
};
class studentlist
{
student *head;
public:
studentlist()
{
head = NULL;
}
void addstudent(string n, string f)
{
student *newstud = new student;
newstud->setname(n);
newstud->setfac(f);
newstud->setnext(head);
head = newstud;
}
void del(string n, string f);
student* gethead()
{
return head;
}
};
and here is the function
void studentlist::del(string n, string f)
{
student *current;
student *aft;
student *prev;
current = head;
while((current != NULL) && (current->getname() == n and current->getfac() == f))
{
prev = current;
current = current->getnext();
if(current = NULL)
return;
if(current->getname() == n and current->getfac() == f)
{
prev = current;
prev->getnext() = current->getnext(); >here is the problem
delete current;
}
I don't understand how prev does not have any value.
C++ noob here. I trying to create a student information program by implementing
a Linked-List class as its data structure.
LinkedList.h
#pragma once
#include <stdexcept>
template <typename T>
class LinkedList
{
private:
struct Node
{
T elem;
Node *prev;
Node *next;
};
Node *header;
Node *trailer;
int size;
public:
LinkedList()
{
header = new Node;
trailer = new Node;
header->next = trailer;
trailer->prev = header;
}
~LinkedList()
{
while (!isEmpty())
removeFirst();
delete header;
delete trailer;
}
const int& n_elem() const
{
return size;
}
const bool isEmpty() const
{
return size == 0;
}
const T& getFirst() const
{
if (isEmpty())
throw std::out_of_range("List is empty.");
return header->next->elem;
}
const T& getLast() const
{
if (isEmpty())
throw std::out_of_range("List is empty.");
return trailer->prev->elem;
}
void addFirst(const T& item)
{
addBetween(item, header, header->next);
}
void addLast(const T& item)
{
addBetween(item, trailer->prev, trailer);
}
void addAt(int index, const T& item)
{
Node *node = header;
for (int i = 0; i < index; i++)
node = node->next;
addBetween(item, node, node->next);
}
const T removeFirst()
{
if (isEmpty())
throw std::out_of_range("List is empty.");
return remove(header->next);
}
const T removeLast()
{
if (isEmpty())
throw std::out_of_range("List is empty.");
return remove(trailer->prev);
}
const T removeAt(int index)
{
if (isEmpty())
throw std::out_of_range("List is empty.");
Node *node = header;
for (int i = 0; i < index; i++)
node = node->next;
return remove(node->next);
}
const T& itemAt(int index) const
{
if (isEmpty())
throw std::out_of_range("List is empty.");
Node *node = header;
for (int i = 0; i < index; i++)
node = node->next;
return node->next->elem;
}
protected:
void addBetween(const T& item, Node *predecessor, Node *successor)
{
Node *newest = new Node;
newest->prev = predecessor;
newest->next = successor;
predecessor->next = newest;
successor->prev = newest;
size++;
}
const T remove(Node *node)
{
Node *predecessor = node->prev;
Node *successor = node->next;
predecessor->next = successor;
successor->prev = predecessor;
T oldItem = node->elem;
size--;
delete node;
return oldItem;
}
};
Student class is defined below.
Program.cpp
#include "stdafx.h"
#include <iostream>
#include <string>
#include "LinkedList.h"
using namespace std;
class Student
{
public:
string name;
string id;
int score;
static const int total = 100;
double grade;
Student(string n, string i, int s)
{
name = n;
id = i;
score = s;
grade = getGrade(score);
}
private:
double getGrade(int score)
{
return (23.0 / 3.0 - ((20.0 * score) / (3.0 * total)));
}
};
LinkedList<Student> l;
int main()
{
//Some code here
return 0;
}
I don't know the reason why
LinkedList<Student> l;
produces an error:
LinkedList<Student>::Node::Node(void)': attempting to reference a deleted function
But when I use:
LinkedList<Student*> l;
there's no error.
Please help.
I'm using Visual Studio 2015.
And sorry for bad English.
In LinkedList<Student>, the inner struct Node looks like this:
struct Node
{
Student elem;
Node *prev;
Node *next;
};
so every Node contains a Student.
However, you'll note that Student has a constructor that takes arguments:
Student(string n, string i, int s)
and it does not have a constructor that does not take arguments.
So if you were to write new Node, the computer would create a Node, and as part of that it would create a Student, but it can't do that because it doesn't have any arguments to give to Student's constructor.
That's (approximately) what "deleted function" means here - normally the compiler would make a Node constructor for you, but in this case it can't.
And so new Node doesn't work, because Node doesn't have a constructor.
Probably the easiest fix here is just to give Student a no-argument constructor as well - something like:
Student()
{
name = "";
id = "";
score = 0;
grade = getGrade(score);
}
I am having a class Car, now I want to make linked list of Car objects. So for this I am having a Node class to hold data for each node.
class StringOfCar;
class Node
{
private:
Node* next;
Car* data;
Node ()
{
next = 0;
data = 0;
}
public:
friend class StringOfCar;
};
And StringOfCar
class StringOfCar
{
private:
Node* head;
Node* tail;
public:
StringOfCar(){
head=0;
tail=0;
}
void output();
void push (Car &);
};
Now I push the elements without any problem with this function :
void StringOfCar::push(Car & new_car)
{
Car *currentCarPtr;
Node *currentNodePtr;
currentNodePtr = new Node;
currentCarPtr = new Car(new_car);
currentNodePtr->next = 0;
currentNodePtr->data = &new_car;
if (head == 0)
{
head = currentNodePtr;
tail = currentNodePtr;
}
else
{
tail->next = currentNodePtr;
tail = currentNodePtr;
}
}
But when I try to output, program stops abruptly.I have output() for Car class also. Output function for both class is as follow :
void StringOfCar::output(){
Node * currentNodePtr = head;
if (head == 0)
cout << "NO cars \n";
else
{
while (currentNodePtr != 0)
{
currentNodePtr->data->output();
currentNodePtr = (currentNodePtr->next);
}
}
}
And for Car class :
void Car::output()
{
cout<<"\nreportingMark "<<setw(3)<<reportingMark;
cout<<"\ncarNumber "<< setw(8)<< carNumber;
cout<<"\nkind " << setw(13)<<KIND_ARRAY[kind];
if (loaded==true)
{
cout<<" \nloaded true";
}
else if (loaded == false)
{
cout<< "\nloaded false";
}
cout<< "\ndestination "<<setw(7)<<destination<<endl;
}
When I comment currentNodePtr->data->output(); this line, it works fine. What can be problem ? Please help
I think the problem is in this line:
currentNodePtr->data = &new_car;
of the function void StringOfCar::push(Car & new_car).
That should be
currentNodePtr->data = currentCarPtr;
I'm running into some problems while trying to use a virtual function within my classes.
I'm using a Linked List to store Employee, Staff and Managers - which inherit each other (Staff and Managers inherit Employee base class).
I need to be able to access a function called getType which returns either "Staff Member" or "Manager" based on which class it is.
this snipit of code is my creation of staff and managers.
Staff staff4 = { "Lisa", "22/02/2012", 0004, HR, 8.9, 34.50 };
Employee* pStaff4 = &staff4;
Employee& testStaff4 = staff4;
myList->addInFront(testStaff4);
Staff staff5 = { "Jade", "23/03/2014", 0003, HR, 6.4, 38.50 };
Employee* pStaff5 = &staff5;
Employee& testStaff5 = staff5;
myList->addInFront(testStaff5);
Manager manager1 = { "Lily", "01/09/2012", 0001, MARKETING, 75968 };
Employee* pMan1 = &manager1;
Employee& testMan1 = manager1;
myList->addInFront(testMan1);
Manager manager2 = { "Craig", "27/03/2011", 0002, HR, 82478 };
Employee* pMan2 = &manager2;
Employee& testMan2 = manager2;
myList->addInFront(testMan2);
//cout << pStaff5->getType();
//system("pause");
This is my employee.h (i've taken out other functions to save space on this post)
class Employee
{
protected:
string name;
string startDate;
unsigned long empNumber;
string dept;
public:
Employee() {};
Employee(string, string, unsigned long, string);
virtual const string getType()
{
return "Emp";
}
};
class Manager : public Employee
{
private:
unsigned long salary;
public:
virtual const string getType()
{
return "Manager";
}
};
class Staff : public Employee
{
private:
float hourlyRate;
float hoursPerWeek;
public:
const string getType()
{
return "Staff Member";
}
};
and finally this is how i'm attempting to call the getType() function:
void displayList(const List& list)
{
List temp(list);
while (!temp.isEmpty())
{
cout << temp.first()->item.getType() << "\n";
cout << temp.first()->item.getName() << "\n";
temp.deleteFirst();
}
}
Here is my list header and .cpp
list.h
//#include <string>
#include "Employees.h"
#define Item Employee
using namespace std;
struct Node
{
Item item;
Node* next;
};
class List
{
private:
Node* head;
Node* end() const;
void copy(const List&);
void destroy();
public:
List();
List(const List&);
~List();
List& operator=(const List&);
bool operator==(const List&);
bool isEmpty() const;
Node* first() ;
Item last() const;
List tail() const;
void addInFront(const Item&);
void addAtEnd(const Item&);
void deleteFirst();
Node* search(const long);
bool searchDelete(const long);
};
list.cpp
#include "stdafx.h"
#include "List.h"
#include <assert.h>
List::List()
{
head = NULL;
}
List::List(const List& otherList) : head(nullptr)
{
copy(otherList);
}
bool List::isEmpty() const
{
return (head == nullptr);
}
Node* List::first()
{
assert(head != nullptr);
return head;
}
void List::deleteFirst()
{
if (head != NULL)
{
Node* tmp = head->next;
delete head;
head = tmp;
}
}
void List::addInFront(const Item& data)
{
Node* nodePtr = new Node;
assert(nodePtr != nullptr);
nodePtr -> item = data;
nodePtr ->next = head;
head = nodePtr;
}
Node* List::search(const long longID)
{
}
bool List::searchDelete(const long longID)
{
Node *temp, *prevNode;
temp = head;
prevNode = NULL;
while (temp != NULL)
{
}
}
Node* List::end() const
{
if (head == nullptr)
return nullptr;
else
{
Node* nodePtr = head;
while (nodePtr->next != nullptr)
{
nodePtr = nodePtr->next;
}
return nodePtr;
}
}
void List::addAtEnd(const Item& data)
{
Node* nodePtr = new Node;
assert(nodePtr != nullptr);
if (head == nullptr)
{
head = nodePtr;
nodePtr->item = data;
}
else
{
nodePtr->item = data;
Node* ptr = end();
ptr->next = nodePtr;
}
}
List& List::operator=(const List& rhs)
{
if (&rhs != this)
{
destroy();
copy(rhs);
}
return *this;
}
void List::copy(const List& otherList)
{
}
void List::destroy()
{
while (head != nullptr)
{
Node* ptr = head;
head = head->next;
delete ptr;
}
}
List::~List()
{
}
apologies about the length of these files.
I'm confused as to why it won't call the appropriate virtual function, as you can see in the first code snipit that i used pStaff5->getType() and that worked - however I can't access the nodes like that once i've stored them in a linked list...(can I?)
Kind regards
Craig
Your list nodes store an Item but that is only the base class. When you try to put a Manager or Staff in the list only the base class part of the object is copied into the list (this is called "slicing") and not the derived parts of the object.
When you call the virtual function you only get the base class overrider for the virtual, because the object stored in the list is only an Employee.
(You should consider making Node and List into templates, instead of doing #define Item Employee)