Trouble accessing protected variables from child class - c++

So, I am trying to implement a stack using a linked list as the parent, and have written these two classes:
template <class T>
class LL {
public:
struct Node {
Node* next = nullptr;
T data = 0;
};
Node* head;
public:
LL();
~LL();
void insert(T item);
void append(T item);
virtual void disp();
};
template<class T>
LL<T>::LL(){ head = nullptr; }
template<class T>
void LL<T>::insert(T item)
{
Node* newNode = new Node;
newNode->data = item;
if (head == nullptr) head = newNode;
else
{
Node* loop = head;
Node* prev = nullptr;
while (loop != nullptr && loop->data < item) {
prev = loop;
loop = loop->next;
}
if (prev == nullptr) { //head
newNode->next = head;
head = newNode;
}
else { //insert
newNode->next = prev->next;
prev->next = newNode;
}
}
}
template<class T>
void LL<T>::append(T item)
{
Node* newNode = new Node;
newNode->data = item;
if (head == nullptr) head = newNode;
else
{
Node* loop = head;
while(loop->next != nullptr)
loop = loop->next;
loop->next = newNode;
}
}
template<class T>
void LL<T>::disp()
{
cout << "[";
if (head) {
if (head->next == nullptr)
cout << head->data;
else {
Node* loop = head;
while (loop->next != nullptr)
{
cout << loop->data << ",";
loop = loop->next;
}
cout << loop->data;
}
}
cout << "]" << endl;
}
template<class T>
LL<T>::~LL()
{
if (head != nullptr) {
while (head != nullptr) {
Node* temp = head;
head = head->next;
delete temp;
temp = nullptr;
}
}
}
template<class T>
class stack: public LL<T> {
private:
public:
stack();
~stack();
virtual void push(T item);
void pop(T ret);
bool empty();
void disp();
};
template<class T>
stack<T>::stack():LL<T>()
{
}
template<class T>
stack<T>::~stack()
{
}
template<class T>
void stack<T>::push(T item){ this->append(item); }
template<class T>
void stack<T>::pop(T ret)
{
ret = this->head->data;
this->head = this->head->next;
}
template<class T>
bool stack<T>::empty() { return false;}
template<class T>
void stack<T>::disp()
{
Node<T>* loop = this->head;
cout << "-" << endl;
while (loop) {
cout << loop->data << endl;
loop = loop->next;
}
cout << "-";
}
The trouble comes in the very last function, "disp()", where it does not give me access to the Node struct. It gives me the error "'Node': identifier not found". This prevents me from declaring the needed "loop" variable. As far as I know, the Node struct should be inherited from the LL class and protected in the stack class. Thus, I should be able to access it directly.
Any ideas?

Ok, so I got around it using this post:
Declaring a struct in a template class, undefined for member functions
My disp() function now looks like this:
template<class T>
void stack<T>::disp()
{
typename LL<T>::Node* loop = this->head;
cout << "-" << endl;
while (loop) {
cout << loop->data << endl;
loop = loop->next;
}
cout << "-";
}

Related

Double Linked Lists Code Revisions

I am having some trouble making the appropriate changes from a post I made on code review. Here is the original post I made here. Specifically, I am at the point where I am revising my insertPosition function.
Previously my function was like this:
template <class T>
void DoubleLinkedLists<T>::insertPosition(int pos, const T& theData) {
Node* prev = new Node;
Node* current = head;
Node* newNode = new Node;
for(int i = 1; i < pos; i++) {
prev = current;
current = current->next;
}
newNode->data = theData;
prev->next = newNode;
newNode->next = current;
}
But now, from what I have been told to do was make it more like this:
Node* cur_node = head;
int i = 0;
while (cur_node) {
if (i++ == pos) {
// do the deed
}
cur_node = cur_node->next;
}
I am not sure what to write in the // do the deed part. What I have tried is this:
template <class T>
void DoubleLinkedLists<T>::insertPosition(int pos, const T& theData) {
Node* current = head;
int i = 0;
while(current) {
if(i++ == pos) {
Node* newNode = new Node;
newNode->data = theData;
newNode->next = newNode->previous;
}
current = current->next;
}
}
But I do not get the code to work at all when I test it out. There are also various other things I need to change I am sure but I would like to get a second opinion of my code I have thus far.
Here is the header file:
#ifndef DoubleLinkedLists_h
#define DoubleLinkedLists_h
template <class T>
class DoubleLinkedLists {
private:
struct Node {
T data;
Node* next;
Node* previous;
};
Node* head;
Node* tail;
public:
// Constructors
DoubleLinkedLists() : head(nullptr), tail(nullptr) {} // empty constructor
DoubleLinkedLists(DoubleLinkedLists const& value); // copy constructor
DoubleLinkedLists<T>(DoubleLinkedLists<T>&& move) noexcept; // move constuctor
DoubleLinkedLists<T>& operator=(DoubleLinkedLists&& move) noexcept; // move assignment operator
~DoubleLinkedLists(); // destructor
// Overload operators
DoubleLinkedLists& operator=(DoubleLinkedLists const& rhs);
friend std::ostream& operator<<(std::ostream& str, DoubleLinkedLists<T> const& data) {
data.display(str);
return str;
}
// Member functions
void swap(DoubleLinkedLists& other) noexcept;
void createNode(const T& theData);
void createNode(T&& theData);
void display(std::ostream& str) const;
void insertHead(const T& theData);
void insertTail(const T& theData);
void insertPosition(int pos, const T& theData);
void deleteHead();
void deleteTail();
void deletePosition(int pos);
bool search(const T& x);
};
template <class T>
DoubleLinkedLists<T>::DoubleLinkedLists(DoubleLinkedLists const& value) : head(nullptr), tail(nullptr) {
for(Node* loop = value->head; loop != nullptr; loop = loop->next) {
createNode(loop->data);
}
}
template <class T>
DoubleLinkedLists<T>::DoubleLinkedLists(DoubleLinkedLists<T>&& move) noexcept : head(nullptr), tail(nullptr) {
move.swap(*this);
}
template <class T>
DoubleLinkedLists<T>& DoubleLinkedLists<T>::operator=(DoubleLinkedLists<T> &&move) noexcept {
move.swap(*this);
return *this;
}
template <class T>
DoubleLinkedLists<T>::~DoubleLinkedLists() {
while(head != nullptr) {
deleteHead();
}
}
template <class T>
DoubleLinkedLists<T>& DoubleLinkedLists<T>::operator=(DoubleLinkedLists const& rhs) {
DoubleLinkedLists copy(rhs);
swap(copy);
return *this;
}
template <class T>
void DoubleLinkedLists<T>::swap(DoubleLinkedLists<T>& other) noexcept {
using std::swap;
swap(head, other.head);
swap(tail, other.tail);
}
template <class T>
void DoubleLinkedLists<T>::createNode(const T& theData) {
Node* newData = new Node;
newData->data = theData;
newData->next = nullptr;
if(head == nullptr) {
newData->previous = nullptr;
head = newData;
tail = newData;
}
else {
newData->previous = tail;
tail->next = newData;
tail = newData;
}
}
template <class T>
void DoubleLinkedLists<T>::createNode(T&& theData) {
Node* newData = new Node;
newData->data = std::move(theData);
newData->next = nullptr;
if(head == nullptr) {
newData->previous = nullptr;
head = newData;
tail = newData;
}
else {
newData->previous = tail;
tail->next = newData;
tail = newData;
}
}
template <class T>
void DoubleLinkedLists<T>::insertHead(const T& theData) {
Node* newNode = new Node;
newNode->data = theData;
newNode->next = head;
head->previous = newNode;
head = newNode;
}
template <class T>
void DoubleLinkedLists<T>::insertTail(const T& theData) {
Node* newNode = new Node;
newNode->data = theData;
newNode->previous = tail;
tail->next = newNode;
tail = newNode;
}
//template <class T>
//void DoubleLinkedLists<T>::insertPosition(int pos, const T& theData) {
// Node* prev = new Node;
// Node* current = head;
// Node* newNode = new Node;
//
// for(int i = 1; i < pos; i++) {
// prev = current;
// current = current->next;
// }
// newNode->data = theData;
// prev->next = newNode;
// newNode->next = current;
//}
template <class T>
void DoubleLinkedLists<T>::insertPosition(int pos, const T& theData) {
Node* current = head;
int i = 0;
while(current) {
if(i++ == pos) {
Node* newNode = new Node;
newNode->data = theData;
newNode->next = newNode->previous;
}
current = current->next;
}
}
template <class T>
void DoubleLinkedLists<T>::display(std::ostream &str) const {
for(Node* loop = head; loop != nullptr; loop = loop->next) {
str << loop->data << "\t";
}
str << "\n";
}
template <class T>
void DoubleLinkedLists<T>::deleteHead() {
Node* old = head;
head = head->next;
delete old;
}
template <class T>
void DoubleLinkedLists<T>::deleteTail() {
Node* prev = nullptr;
Node* current = head;
while(current->next != nullptr) {
prev = current;
current = current->next;
}
tail = prev;
prev->next = nullptr;
delete current;
}
template <class T>
void DoubleLinkedLists<T>::deletePosition(int pos) {
Node* prev = new Node;
Node* current = head;
for(int i = 1; i < pos; i++) {
prev = current;
current = current->next;
}
prev->next = current->next;
}
template <class T>
bool DoubleLinkedLists<T>::search(const T &x) {
Node* current = head;
while(current != nullptr) {
if(current->data == x) {
return true;
}
current = current->next;
}
return false;
}
#endif /* DoubleLinkedLists_h */
Here is the main.cpp file to test the above implementation:
#include <iostream>
#include "DoubleLinkedLists.h"
int main(int argc, const char * argv[]) {
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////// Double Linked List //////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
DoubleLinkedLists<int> obj;
obj.createNode(2);
obj.createNode(4);
obj.createNode(6);
obj.createNode(8);
obj.createNode(10);
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"---------------Displaying All nodes---------------";
std::cout<<"\n--------------------------------------------------\n";
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"----------------Inserting At Start----------------";
std::cout<<"\n--------------------------------------------------\n";
obj.insertHead(50);
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"-----------------Inserting At End-----------------";
std::cout<<"\n--------------------------------------------------\n";
obj.insertTail(20);
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"-------------Inserting At Particular--------------";
std::cout<<"\n--------------------------------------------------\n";
obj.insertPosition(5,60);
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"----------------Deleting At Start-----------------";
std::cout<<"\n--------------------------------------------------\n";
obj.deleteHead();
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"----------------Deleting At End-----------------";
std::cout<<"\n--------------------------------------------------\n";
obj.deleteTail();
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"--------------Deleting At Particular--------------";
std::cout<<"\n--------------------------------------------------\n";
obj.deletePosition(4);
std::cout << obj << std::endl;
std::cout << std::endl;
obj.search(8) ? printf("Yes"):printf("No");
return 0;
}
Update:
This is what I have done so far, I am pass in the data into a new node and then link previous node with the next node. Although, the code runs but nothing actually gets inserted into a position so I believe it does not even go through the while loop. I am not sure what the problem is.
template <class T>
void DoubleLinkedLists<T>::insertPosition(int pos, const T& theData) {
Node* current = head;
int i = 0;
while(current) {
if(i++ == pos) {
Node* newNode = new Node;
newNode->data = theData;
newNode->previous = newNode->next;
}
current = current->next;
}
}
So...
template <class T>
void DoubleLinkedLists<T>::insertPosition(int pos, const T& theData) {
Node* current = head;
int i = 0;
while (current != nullptr) {
if (i++ == pos) {
Node* newNode = new Node;
newNode->data = theData;
// Let's do the wiring
newNode->previous = current->previous;
newNode->next = current;
if (newNode->previous != nullptr) { // If the node is inserted at the end
newNode->previous->next = newNode;
}
current->previous = newNode;
return;
}
current = current->next;
}
}

Deleting at some position in a double linked list

I am having some trouble with this function I wrote to delete at some position in a double linked list. I feel like I am leaking memory and I am not doing this property for a double linked list.
Here is the code:
template <class T>
void DoubleLinkedLists<T>::deletePosition(int pos) {
Node* prev = new Node;
Node* current = head;
for(int i = 1; i < pos; i++) {
prev = current;
current = current->next;
}
prev->next = current->next;
}
This is pretty much what I did for a single linked list so I know this is not right. If anyone has any suggestions on how to do this for a double linked list I would really appreciate it.
EDIT:
I think this works correctly now:
template <class T>
void DoubleLinkedLists<T>::deletePosition(int pos) {
Node* temp = nullptr;
Node* current = head;
for(int i = 1; i < pos; i++) {
temp = current;
current = current->next;
}
temp->previous = current->previous;
temp->next = current->next;
}
Here is the entire code:
#ifndef DoubleLinkedLists_h
#define DoubleLinkedLists_h
template <class T>
class DoubleLinkedLists {
private:
struct Node {
T data;
Node* next;
Node* previous;
};
Node* head;
Node* tail;
public:
// Constructors
DoubleLinkedLists() : head(nullptr), tail(nullptr) {} // empty constructor
DoubleLinkedLists(DoubleLinkedLists const& value); // copy constructor
DoubleLinkedLists<T>(DoubleLinkedLists<T>&& move) noexcept; // move constuctor
DoubleLinkedLists<T>& operator=(DoubleLinkedLists&& move) noexcept; // move assignment operator
~DoubleLinkedLists(); // destructor
// Overload operators
DoubleLinkedLists& operator=(DoubleLinkedLists const& rhs);
friend std::ostream& operator<<(std::ostream& str, DoubleLinkedLists<T> const& data) {
data.display(str);
return str;
}
// Member functions
void swap(DoubleLinkedLists& other) noexcept;
void push(const T& theData);
void push(T&& theData);
void display(std::ostream& str) const;
void insertHead(const T& theData);
void insertTail(const T& theData);
void insertPosition(int pos, const T& theData);
void deleteHead();
void deleteTail();
void deletePosition(int pos);
bool search(const T& x);
};
template <class T>
DoubleLinkedLists<T>::DoubleLinkedLists(DoubleLinkedLists const& value) : head(nullptr), tail(nullptr) {
for(Node* loop = value->head; loop != nullptr; loop = loop->next) {
push(loop->data);
}
}
template <class T>
DoubleLinkedLists<T>::DoubleLinkedLists(DoubleLinkedLists<T>&& move) noexcept : head(nullptr), tail(nullptr) {
move.swap(*this);
}
template <class T>
DoubleLinkedLists<T>& DoubleLinkedLists<T>::operator=(DoubleLinkedLists<T> &&move) noexcept {
move.swap(*this);
return *this;
}
template <class T>
DoubleLinkedLists<T>::~DoubleLinkedLists() {
while(head != nullptr) {
deleteHead();
}
}
template <class T>
void DoubleLinkedLists<T>::swap(DoubleLinkedLists<T> &other) noexcept {
using std::swap;
swap(head,other.head);
swap(tail,other.tail);
}
template <class T>
void DoubleLinkedLists<T>::push(const T& theData) {
Node* newNode = new Node;
newNode->data = theData;
newNode->previous = tail;
if(head == nullptr) {
head = newNode;
}
else {
tail->next = newNode;
}
tail = newNode;
}
template <class T>
void DoubleLinkedLists<T>::push(T&& theData) {
Node* newNode = new Node;
newNode->data = theData;
newNode->previous = tail;
if(head == nullptr) {
head = newNode;
}
else {
tail->next = newNode;
}
tail = newNode;
}
template <class T>
void DoubleLinkedLists<T>::display(std::ostream &str) const {
for(Node* loop = head; loop != nullptr; loop = loop->next) {
str << loop->data << "\t";
}
str << "\n";
}
template <class T>
void DoubleLinkedLists<T>::insertHead(const T &theData) {
Node* newNode = new Node;
newNode->data = theData;
newNode->next = head;
head->previous = newNode;
head = newNode;
}
template <class T>
void DoubleLinkedLists<T>::insertTail(const T &theData) {
Node* newNode = new Node;
newNode->data = theData;
newNode->previous = tail;
tail->next = newNode;
tail = newNode;
}
template <class T>
void DoubleLinkedLists<T>::insertPosition(int pos, const T &theData) {
if (pos < 0) {
throw std::invalid_argument("pos is not a valid index");
}
Node* current = head;
Node* previous = nullptr;
while(pos-- > 0) {
if(!current) {
throw std::invalid_argument("pos is not a valid index");
}
previous = current;
current = current->next;
}
Node* newNode = new Node;
newNode->data = theData;
newNode->previous = previous;
newNode->next = current;
if(newNode->previous) {
newNode->previous->next = newNode;
}
else {
head = newNode;
}
if(newNode->next) {
newNode->next->previous = newNode;
}
else {
tail = newNode;
}
}
template <class T>
void DoubleLinkedLists<T>::deleteHead() {
if (head != nullptr) {
Node* old = head;
head = head->next;
delete old;
}
else {
throw std::invalid_argument("the list is empty!");
}
}
template <class T>
void DoubleLinkedLists<T>::deleteTail() {
if(head != nullptr) {
Node* prev = nullptr;
Node* current = head;
while(current->next != nullptr) {
prev = current;
current = current->next;
}
tail = prev;
prev->next = nullptr;
delete current;
}
else {
throw std::invalid_argument("The list is already empty, nothing to delete.");
}
}
template <class T>
void DoubleLinkedLists<T>::deletePosition(int pos) {
Node* temp = nullptr;
Node* current = head;
for(int i = 1; i < pos; i++) {
temp = current;
current = current->next;
}
temp->previous = current->previous;
temp->next = current->next;
}
template <class T>
bool DoubleLinkedLists<T>::search(const T &x) {
Node* current = head;
while(current != nullptr) {
if(current->data == x) {
return true;
}
current = current->next;
}
return false;
}
#endif /* DoubleLinkedLists_h */
And here is the main.cpp file that tests it:
#include <iostream>
#include "DoubleLinkedLists.h"
int main(int argc, const char * argv[]) {
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////// Double Linked List //////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
DoubleLinkedLists<int> obj;
obj.push(2);
obj.push(4);
obj.push(6);
obj.push(8);
obj.push(10);
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"---------------Displaying All nodes---------------";
std::cout<<"\n--------------------------------------------------\n";
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"----------------Inserting At Start----------------";
std::cout<<"\n--------------------------------------------------\n";
obj.insertHead(50);
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"-----------------Inserting At End-----------------";
std::cout<<"\n--------------------------------------------------\n";
obj.insertTail(20);
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"-------------Inserting At Particular--------------";
std::cout<<"\n--------------------------------------------------\n";
obj.insertPosition(5,60);
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"----------------Deleting At Start-----------------";
std::cout<<"\n--------------------------------------------------\n";
obj.deleteHead();
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"----------------Deleting At End-----------------";
std::cout<<"\n--------------------------------------------------\n";
obj.deleteTail();
std::cout << obj << std::endl;
std::cout<<"\n--------------------------------------------------\n";
std::cout<<"--------------Deleting At Particular--------------";
std::cout<<"\n--------------------------------------------------\n";
obj.deletePosition(5);
std::cout << obj << std::endl;
std::cout << std::endl;
obj.search(8) ? printf("Yes"):printf("No");
return 0;
}
So you would need to do something like this. Note that your code does not handle the case of an index out of range (i.e. the position specified is either negative or is longer the list). It looked like you don't maintain a count of your list length (in the linked code) so I added a check for current != nullptr into the for loop as well as after the for loop to handle the case of the pos being longer than the list. In that case, now the code will do nothing, but you could throw an out of range exception or something like that to indicate the invalid condition. In the case of removing the head you also need to take care to fix up the head pointer. I am assuming you might have a tail pointer as well, so you need to add checks to see if you are removing the tail and fix that up as well.
Note
I didn't compile this and so there may be a typo or two, but it should at least point you in the right direction.
void DoubleLinkedLists<T>::deletePosition(int pos) {
if (pos < 0) {} // Should do something in this case
Node* current = head;
// Added null check to keep from continuing past the end of the list
for(int i = 1; i < pos && current != nullptr; i++) {
current = current->next;
}
if (current != nullptr)
{
// If we are at the head, there isn't a previous
if (current != head)
{
current->previous->next = current->next;
}
else
{
// In this case, we are removing the head, need to reset head to the next Node
head = current->next;
}
if (current->next != nullptr)
{
current->next->previous = current->previous;
}
else if (current == tail)
{
// In this case we are removing the tail, need to reset tail pointer
tail = current->previous;
}
delete current; // Cleans up the node we are deleting
}
}

Why am I getting segmentation fault for when calling templated overloaded operator in c++?

I AM NOT ALLOWED TO USE STL CONTAINERS!
I am getting a Segmentation fault from the SortedListClass(const SortedListClass< T > &rhs), operator=(const SortedListClass< T > &rhs), and clear() functions in the following code.
This is the result from the debugger:
#0 __GI___libc_free (mem=0x4) at malloc.c:2929
#1 0x00000000004016d6 in SortedListClass::clear (this=0x7ffffffde470) at SortedListClass.inl:45
#2 0x00000000004011b5 in SortedListClass::operator= (this=0x7ffffffde470, rhs=...) at SortedListClass.inl:28
#3 0x0000000000400c88 in main () at project5.cpp:33
SortedListClass.inl line 45 is the following: delete tempHead;
SortedListClass.inl line 28 is the following: this->clear();
project5.cpp line 33 is the following: copyTestList = testList;
Here is the code:
SortedListClass.inl
template<class T>
SortedListClass< T >::SortedListClass()
{
head = NULL;
tail = NULL;
cout<<"Empty list intialized...."<<endl;
}
template<class T>
SortedListClass< T >::SortedListClass(const SortedListClass< T > &rhs)
{
cout<<"Copied Value(s)"<<endl;
LinkedNodeClass< T > *rhsFront;
LinkedNodeClass< T > *newCopyNode;
rhsFront = rhs.head;
while(rhsFront != NULL)
{
newCopyNode = new LinkedNodeClass< T >(rhsFront,rhsFront->getValue(),
rhsFront->getNext());
rhsFront = newCopyNode;
rhsFront = rhsFront->getNext();
}
}
template<class T>
void SortedListClass< T >::operator=(const SortedListClass< T > &rhs)
{
this->clear();
*this = SortedListClass(rhs);
}
template<class T>
void SortedListClass< T >::clear()
{
LinkedNodeClass< T >*tempHead;
LinkedNodeClass< T >*tempTail;
tempHead = head;
tempTail = tail;
while(tempHead != NULL || tempTail != NULL)
{
cout << "Deleting node(s) --> "<< endl;
tempHead = head;
delete tempHead;
tempHead = NULL;
head = tempHead;
tempTail = tail;
delete tempTail;
tempTail = NULL;
tail = tempTail;
}
cout<<"Deleting complete"<<endl;
}
project5.cpp
int main()
{
SortedListClass< int >testList;
testList.insertValue(3);
testList.printForward();
testList.insertValue(4);
testList.printForward();
int theVal = 0;
SortedListClass<int>copyTestList(testList);
copyTestList = testList;
copyTestList.getNumElems();
int index = 0;
int outval = 0;
copyTestList.getElemAtIndex(index,outval);
copyTestList.printForward();
copyTestList.removeLast(theVal);
copyTestList.printBackward();
return 0 ;
}
The code you have shown for SortedListClass.inl is incomplete, but the pieces you have shown are all wrong. Try something more like this instead:
template<class T>
SortedListClass<T>::SortedListClass()
: head(NULL), tail(NULL) /*, init other members as needed ... */
{
cout << "Empty list initialized...." << endl;
}
template<class T>
SortedListClass<T>::SortedListClass(const SortedListClass<T> &rhs)
: head(NULL), tail(NULL) /*, init other members as needed ... */
{
cout << "Copying value(s)" << endl;
LinkedNodeClass<T> *rhsNode = rhs.head;
while (rhsNode)
{
insertValue(rhsNode->getValue());
rhsNode = rhsNode->getNext();
}
cout << "Copying complete" << endl;
}
template<class T>
SortedListClass<T>::~SortedListClass()
{
clear();
}
template<class T>
SortedListClass<T>& SortedListClass<T>::operator=(const SortedListClass<T> &rhs)
{
if (&rhs != this)
{
SortedListClass<T> tempList(rhs);
std::swap(head, tempList.head);
std::swap(tail, tempList.tail);
// swap other members as needed ...
}
return *this;
}
template<class T>
void SortedListClass<T>::clear()
{
cout << "Deleting node(s)" << endl;
LinkedNodeClass<T> *tempNode = head;
head = NULL;
tail = NULL;
// reset other members as needed ...
while (tempNode)
{
LinkedNodeClass<T> *tempNext = tempNode->getNext();
delete tempNode;
tempNode = tempNext;
}
cout << "Deleting complete" << endl;
}
template<class T>
void SortedListClass<T>::insertValue(const T &value)
{
LinkedNodeClass<T> *newNode = new LinkedNodeClass<T>(tail, value, NULL);
if (!head)
head = newNode;
if (tail)
tail->setNext(newNode);
tail = newNode;
// increment size counter, if applicable...
}
template<class T>
void SortedListClass<T>::removeLast(const T &value)
{
LinkedNodeClass<T> *tempNode = tail;
while (tempNode)
{
LinkedNodeClass<T> *tempPrevious = tempNode->getPrevious();
if (tempNode->getValue() == value)
{
LinkedNodeClass<T> *tempNext = tempNode->getNext();
if (tempPrevious)
tempPrevious->setNext(tempNext);
if (tempNext)
tempNext->setPrevious(tempPrevious);
if (tempNode == tail)
tail = tempPrevious;
if (tempNode == head)
head = tempNext;
delete tempNode;
// decrement size counter, if applicable...
return;
}
tempNode = tempPrevious;
}
}

Linking Doubly linked list with Stack and Queue classes in C++

so I have an assignment where I need to create a doubly linked list and then create a stack and queue class and inherit from the linkedlist class in order to create an RPN calculator. So far I have created my doubly linkedlist class and the other to classes. However, I am having trouble understanding how I will inherit and use the linked list class with the stack and queue. I will provide what I have so far.
I have gone to tutoring and have not had much help so I thought I would look for some extra help, do not want homework done for me but to just be pointed in the right direction.
Stack.h
using std::iterator;
using std::vector;
using std::string;
template<class T>
class Stack : public vector<T>
{
private:
T getElement(bool erase);
typename std::vector<T> ::iterator pEnd;
T top;
public:
Stack();
T pop();
T peek();
void push(T elem);
};
template<class T>
Stack<T>::Stack()
{
}
template<class T>
void Stack<T>::push(T elem)
{
this->push_back(elem);
}
template<class T>
T Stack<T>::peek()
{
return this->getElement(false);
}
template<class T>
T Stack<T>::pop()
{
return this->getElement(true);
}
template<class T>
T Stack<T>::getElement(bool erase)
{
this->pEnd = this->end() - 1;
T tmp;
if (this->size() > 0)
{
tmp = *this->pEnd;
if (erase) {
this->erase(pEnd);
}
}
return tmp;
}
Queue.h
using namespace std;
class Queue
{
private:
int items[MAXQUEUE];
int head;
int tail;
public:
Queue();
bool isEmpty();
bool isFull();
bool enqueue(int item);
int dequeue();
int peek();
};
Queue::Queue()
:head(QEMPTY), tail(QEMPTY)
{
}
bool Queue::isEmpty()
{
return this->head == this->tail;
}
bool Queue::isFull()
{
return this->tail == MAXQUEUE;
}
bool Queue::enqueue(int item)
{
if (this->isFull())
return false;
this->items[this->tail] = item;
tail = (tail + 1) % MAXQUEUE;
return true;
}
int Queue::dequeue()
{
if (this->isEmpty())
return EMPTY;
int item = this->items[head];
this->head = (this->head + 1) % MAXQUEUE;
return item;
}
int Queue::peek() {
return this->tail;
}
doublylinkedlist.h
using std::iterator;
using std::vector;
using std::string;
/*START OF NODE CLASS*/
/*---------------------------------------------*/
template<class T>
struct Node
{
T Data;
T Search;
T value;
Node<T>*Next;
Node<T>*Prev;
};
template<class T>
class LinkedList
{
private:
Node<T> *Head;
public:
LinkedList();
void addNode(T Data);
void deleteNode(T Search);
void insert(T Search, T value);
void printListBackwards();
void printListForwards();
};
template<class T>
LinkedList<T>::LinkedList()
{
this->Head = NULL;
}
template<class T>
void LinkedList<T>::addNode(T data)
{
if (Head == NULL)
{
Head = new Node<T>;
Head->Data = data;
Head->Next = NULL;
Head->Prev = NULL;
}
else
{
Node<T>*p = this->Head;
while (p->Next != NULL)
p = p->Next;
Node<T>*n = new Node<T>;
n->Data = data;
n->Next = NULL;
p->Next = n;
n->Prev = p;
}
}
template<class T>
void LinkedList<T>::insert(T Search, T value)
{
Node *p = Head;
while (p->Data != Search)
{
p = p->Next;
}
Node *n = new Node;
n->Data = value;
n->Next = p->Next;
p->Next = n;
}
template<class T>
void LinkedList<T>::deleteNode(T Search)
{
Node *p = Head;
while (p->Next->Data != Search)
{
p = p->Next;
}
Node *delPtr = p->Next;
p->Next = p->Next->Next;
delete delPtr;
}
template<class T>
void LinkedList<T>::printListBackwards()
{
Node<T> *p = Head;
while (p->Next != NULL)
{
p = p->Next;
}
while (p != NULL)
{
cout << p->Data<< endl;
p = p->Prev;
}
}
template<class T>
void LinkedList<T>::printListForwards()
{
Node<T> *p = Head;
while (p != NULL)
{
cout << p->Data << endl;
p = p->Next;
}
}
A doubly linked list can be added to at the head or the tail, and removed at the tail.
A stack pushes at one end (the head?) and pops at the same end (the head).
A queue pushes at one end (the tail) and pops at the other end (the head).

Inserting two elements in node template in a doubly linked list

I'm new with data structures in C++, and i'm trying to do a doubly linked list with templates. All the examples that i have seen are only for 1 element of the template node, so i'm trying to put 2 elements in the template node in the list, but i don't know how to do it, anyway, i tried to make the list.
Here's the code:
#include<iostream>
#include<cstring>
using namespace std;
template<class T>
// node class
class node
{
public:
node();
node(T);
~node();
node *next;
T data[2];
void borra_todo();
void print();
};
// by defect
template<typename T>
node<T>::node()
{
data[0] = NULL;
data[1] = NULL;
next = NULL;
}
// by parameter
template<typename T>
node<T>::node(T data_)
{
data[0] = data_[0];
data[1] = data_[1];
next = NULL;
}
// delete nodes
template<typename T>
void node<T>::borra_todo()
{
if (next)
next->borra_todo();
delete this;
}
// node printing
template<typename T>
void node<T>::print()
{
cout << data[0] << " " << data[1] << "->";
}
template<typename T>
node<T>::~node() {}
// list
template <class T>
class list
{
private:
node<T> *m_head;
int m_num_nodes;
public:
list();
~list();
void add_head(T);
void add_end(T);
void add_sort(T);
void fill(char r[30], char n[30]);
void search(T);
void del_by_data(T);
void print();
};
template<typename T>
list<T>::list()
{
m_num_nodes = 0;
m_head = NULL;
}
//add in the beginning
template<typename T>
void list<T>::add_head(T data_)
{
node<T> *new_node = new node<T>(data_);
node<T> *temp = m_head;
if (!m_head)
{
m_head = new_node;
}
else
{
new_node->next = m_head;
m_head = new_node;
while (temp)
{
temp = temp->next;
}
}
m_num_nodes++;
}
// add to the last
template<typename T>
void list<T>::add_end(T data_)
{
node<T> *new_node = new node<T> (data_);
node<T> *temp = m_head;
if (!m_head)
{
m_head = new_node;
}
else
{
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = new_node;
}
m_num_nodes++;
}
// it is supposed that sorts items in the list ...
template<typename T>
void list<T>::add_sort(T data_)
{
node<T> *new_node = new node<T> (data_);
node<T> *temp = m_head;
if (!m_head)
{
m_head = new_node;
}
else
{
for (int i =0; i <= 1; i++)
{
if (m_head->data[0] > data_[i])
{
new_node->next = m_head;
m_head = new_node;
}
else
{
while ((temp->next != NULL) && (temp->next->data[0] < data_[i]))
{
temp = temp->next;
}
new_node->next = temp->next;
temp->next = new_node;
}
}
m_num_nodes++;
}
}
// sort adding ...
template<typename T>
void list<T>::fill(char rfc[30])
{
char temprfc[30];
char tempnombre[30];
temprfc = "DUDE010101R0";
tempnombre = "Dude";
add_sort(temprfc, tempnombre);
temprfc = "AUDE010101R1";
tempnombre = "Commander";
add_sort(temprfc, tempnombre);
}
// print list
template<typename T>
void list<T>::print()
{
node<T> *temp = m_head;
if (!m_head)
{
cout << "List is empty" << endl;
}
else
{
while (temp)
{
temp->print();
if (!temp->next)
cout << "NULL\n";
temp = temp->next;
}
}
cout << endl;
}
// search the list
template<typename T>
void list<T>::search(T data_)
{
node<T> *temp=m_head;
int cont=1;
int cont2=0;
while(temp)
{
if(strcmp(temp->data,data_[0]))
{
cout<<"Element found " << temp->data;
cout << " in position: " << cont << endl;
cont2++;
}
temp=temp->next;
cont++;
}
if(cont2==0)
{
cout << "Element not found"<<endl;
}
}
// ... delete by data
template<typename T>
void list<T>::del_by_data(T data_)
{
node<T> *temp = m_head;
node<T> *temp1 = m_head->next;
int cont =0;
if (m_head->data == data_)
{
m_head = temp->next;
}
else
{
while (temp1)
{
if (temp1->data == data_)
{
node<T> *aux_node = temp1;
temp->next = temp1->next;
delete aux_node;
cont++;
m_num_nodes--;
}
temp = temp->next;
temp1 = temp1->next;
}
}
if (cont == 0)
{
cout << "No data" << endl;
}
}
// destroy the constructor
template<typename T>
list<T>::~list() {}
int main()
{
list<char> list1;
char element1[30];
char element2[30];
int dim, choice, pos;
do{
cout << "Select a choice.\n";
cout << "1. Print list\n";
cout << "2. Delete an element of the list\n";
cout << "3. Search an element of the list\n";
cout << "4. Exit\n";
cin >> choice;
switch(choice)
{
case 1:
{
cout << "Printing list:\n";
list1.fill("1","2");
list1.print();
break;
}
case 2:
{
cout << "Element to delete: ";
cin >> element1;
list1.search(element1);
element1 = "";
break;
}
case 3:
{
cout << "Element to search: ";
cin >> element1;
list1.search(element1);
element1 = "";
break;
}
}
}while(choice != 4);
return 0;
}
The code doesn't compile, it marks errors like:
" error: prototype for ‘void list::fill(char*)’ does not match any in class ‘list’
void list::fill(char rfc[30])
^
t3b.cpp:79:8: error: candidate is: void list::fill(char*, char*)
void fill(char r[30], char n[30]);"
Any ideas on how to fix it? Or any ideas on how to put 2 elements in a node using templates?
Thanks in advance.
Dude, you should really try to isolate the error a little bit before posting it. This is 500 lines of code, I had to copy and paste it all into an editor before I could even look at it.
When you declared fill, it had two arguments, when you defined it, it had one. Also, I would avoid arrays of characters for numerous reasons, instead use std::string.