i have the following classes:
class mypipe {
class node {
public:
char ch;
node* next;
node(){...}
node(char c){..}
} ;
public:
unsigned int size;
node* head;
and i need to overload the operator<<, to print the mypipe as it is now.
then, i'm trying to write the following:
friend ostream& operator<< (ostream& stream, mypipe p) {
node* curr = p.head -> next;
...
immediately after the variables definition.
the problem is that i get an error "identifier node is undefined".
i've tried to declare the operator and implement it outside of the class, that didn't help.
does anyone have any ideas about it?
thanks in advance for anyone who can help :)
node is an inner class, which means you have to qualify its type:
mypipe::node* curr = p.head -> next;
Related
I am trying to overload the ostream << operator for class List
class Node
{
public:
int data;
Node *next;
};
class List
{
private:
Node *head;
public:
List() : head(NULL) {}
void insert(int d, int index){ ... }
...}
To my humble knowledge (overload ostream functions) must be written outside the class. So, I have done this:
ostream &operator<<(ostream &out, List L)
{
Node *currNode = L.head;
while (currNode != NULL)
{
out << currNode->data << " ";
currNode = currNode->next;
}
return out;
}
But of course, this doesn't work because the member Node head is private.
What are the methods that can be done in this case other than turning Node *head to public?
You can solve this by adding a friend declaration for the overloaded operator<< inside class' definition as shown below:
class List
{
//add friend declaration
friend std::ostream& operator<<(std::ostream &out, List L);
//other member here
};
Declare the function signature inside the class and mark it as friend, then define it outside the class if you want.
Everything was working before I introduced templates to my code
EDIT:
Here is the problem to which I was able to narrow it down, thanks to your tips:
In file included from main.cpp:4:
stack.cpp: In member function void Stack<TYPE>::push(Stack<TYPE>&, TYPE)':
stack.cpp:35: error:node' is not a type
I wonder if a similar problem could appear later in the pop function, but it seems like it does not.
I'm confused as to why it seems to insist that node is not a type.
EDIT#2:
this statement in the main.cpp file is now causing trouble. I have moved all the definitions out of stack.cpp to stack.h. After this Stack<int> list;my compiles says Segmentation fault (core dumped).
stack.h:
#include <iostream>
using namespace std;
template <typename TYPE>
struct node {
TYPE data;
node<Type> *next;
node(){
data = NULL;
next = NULL;
}
~node(){
if (data!=0)
delete next;
}
explicit node(int i){
data = i;
}
};
template <typename TYPE>
class Stack {
private:
node<TYPE> *top;
void init();
public:
Stack(); // default constructor
virtual ~Stack(); // destructor
bool empty();
void push(Stack&,TYPE);
TYPE pop(Stack&);
int peek();
void clear();
ostream& printf(ostream&, node<TYPE> *);
ostream& print(ostream&);
ostream& sequentialPrint(Stack&,ostream&);
ostream& reversePrint(Stack&,ostream&);
friend ostream& operator<<(ostream&, Stack&);
};
stack.cpp:
template <typename TYPE>
void Stack<TYPE>::push(Stack<TYPE> &s, TYPE i) {
node<TYPE> * n = new node(i);
n->next = top;
top = n;
}
template <typename TYPE>
TYPE Stack<TYPE>::pop(Stack<TYPE> &s){
if (empty()) {
cerr<<"Stack is empty \n";
}
TYPE temp = s.top->data;
top = top->next;
return temp;
}
friend ostream& operator<<(ostream&, Stack&); is not needed
you can't define template methods in cpp file. Every element of template which is template parameter depended must be defined in header file.
My header file
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include <iostream>
#include <string>
using namespace std;
class Node
{
friend class LinkedList;
public:
Node(string& name, int num) :studentName(name), RUID(num)
{
this->next = NULL;
}
private:
string studentName;
int RUID;
Node *next;
};
class LinkedList
{
public:
LinkedList();
~LinkedList();
LinkedList operator+(const LinkedList &i); //Done
LinkedList operator=(const LinkedList &j);
void makeLists(int n); //Done
void addNode(LinkedList &i);
void removeNode();
void printList();
void printElement();
void sortList();
private:
Node *head;
Node *tail;
int size;
};
#endif
My function
LinkedList LinkedList::operator=(LinkedList &j)
{
if (&j != this)
{
Node* temp = j.head;
while (temp->next != nullptr)
{
j.head = j.head->next;
delete temp;
temp = j.head;
}
temp = j.head;
while (temp != nullptr)
{
}
}
return *this;
}
I've tried for hours but I'm stumped as to what I should do within my second while loop. In fact, I don't even know if my operator overloading function is even remotely correct but that was the best I was able to come up within the past few hours or so
For starters, let's fix the code that you have already written. Looks like you have a perfectly written "removeNode()" class method. You haven't actually shown it, but I'll assume that it works perfectly.
If that is the case, it's a waste and duplicated code to also go through the motions of deleting the list's existing nodes. You should have already written this code as part of your removeNode() method. So, replace the code that you have written here with a simple loop that invokes removeNode(), until the list is empty.
After you've gone through this excersize, you should be able to figure it out all by yourself that your second while() loop should simply iterate over the nodes in the other list, and use this list's addNode() method to add a copy of each node from the other list, to this list.
I have been trying for quite a while to figure out how to get pointers for my nodes to merge two linked lists. I have to do it with the following function definition (NB I have found plenty of answers when the pointers are arguments to a member function but in my case I have to do it with a reference. Any pointers :) would be appreciated. NB I know that my code is not yet fully developed but I really need to get pointers to both OrderedList objects to make it work. ie if I can get two pointers to the _head of each ordered link list I think I can generate the code.
Any help to get a valid reference for curr and mov would be appreciated.
OrderedList operator+(OrderedList&second) // merges two OrderedLists
{
int i=1;
int j=1;
Node* prev = NULL;
Node* curr = this->_head;
Node* mov = second._head;
while (curr!=NULL and mov!=NULL)
{
if (this->operator [](i)<= second->operator [](j) or mov->next == NULL)
{
i++;
}else{
prev->next = mov;
mov = mov->next;
mov = curr;
}
}
return OrderedList;
}
so this is for an assignment so I want to learn how to do it correctly. I am not just interested in answers but mainly understanding. I am new to c++. So basically we have been given a header file and have to make all the member and friend functions work. I am stuck on how to make this operator function work. So the header file is:
#ifndef ORDEREDLIST_H_
#define ORDEREDLIST_H_
#include <iostream>
using namespace std;
class Node
{
public:
double item; // data item
Node *next; // pointer to next node
};
class OrderedList
{
// friend operator functions
friend ostream &operator<<(ostream &, const OrderedList &);
friend istream &operator>>(istream &, OrderedList &);
public:
// constructors
OrderedList():_head(NULL),_size(0) {};
OrderedList(const OrderedList &); // copy constructor
// destructor
~OrderedList();
// operator functions
OrderedList operator+(OrderedList&); // merges two OrderedLists
double operator[](int) const; // subscript operator returns rvalue
const OrderedList &operator=(const OrderedList &); // assignment
void insert(double); // inserts an item
bool remove(int); // remove i th item
void pop(); // pop the first item
//void printlist(Node*);
private:
Node *_head;
int _size;
};
#endif /* ORDEREDLIST_H_ */
Can I only get a pointer if the overloaded operator is a friend of OrderedList or if it is a member function? That is what I am seeing but I am very new to C++.
I'm not very good at this, and I am a bit stuck making the copy constructor for a single linked list and the nodes that go with it.
Here is my header file:
#pragma once
#include <iostream>
using namespace std;
class Node
{
public:
int data;
Node* next;
Node()
{
next = NULL;
data = 0;
}
Node(const Node& copyNode); /*: data(copyNode.data), next(copyNode.next ? new Node(*copyNode.next) : NULL)*/
};
class SLLIntStorage
{
public:
Node* head;
Node* current;
Node* tail;
void Read(istream&);
void Write(ostream&);
void setReadSort(bool);
void sortOwn();
void print();
void mergeSort(Node**);
Node *merge(Node*, Node*);
void split(Node*, Node**, Node**);
bool _sortRead;
int numberOfInts;
SLLIntStorage(const SLLIntStorage& copying) //: head(copying.head ? new Node(*copying.head) : NULL)
{
}
SLLIntStorage(void);
~SLLIntStorage(void);
};
inline ostream& operator<< (ostream& out, SLLIntStorage& n)
{
n.Write(out);
return out;
}
inline istream& operator>> (istream& in, SLLIntStorage& s)
{
s.Read(in);
return in;
}
Could anyone give me a hand on understanding how this works and what I could do to create it? Thank you.
To copy a linked list, you must iterate the entire linked list and make a copy of each of the nodes, and append that to the new list. Remember that you don't just copy the pointers, but you must copy the entire Node structure and any data that needs copying as well (e.g. if the datas are pointers, you'll need to do deep copying on those too).
So here's an example copy constructor for your SLLIntStorage class:
SLLIntStorage(const SLLIntStorage& copying) : head(NULL)
{
Node* cur = copying.head;
Node* end = NULL;
while (cur)
{
Node* n = new Node;
n->data = cur->data;
if (!head) {
head = n;
end = head;
} else {
end->next = n;
end = n;
}
cur = cur->next;
}
}
Note that I didn't take into account the tail and current data members, etc. You'll have to account for those.
As it is homework, I will try to give the idea from which you can figure out what you need to do with the copy constructors.
Node(const Node& copyNode) : data(copyNode.data),
next(copyNode.next)
{
// ....
}
In the above snippet you are just actually making the next to point the location copyNode::next is pointing to. So, you run in to problems when any of the pointer deallocates the resource it is pointing to leaving the other dangling.
So, you should make the pointer next each instance to point to a location it independently holds. So, -
Node(const Node& copyNode) : data(copyNode.data),
next(new Node)
{
(*next) = *(copyNode.next) ;
// ....
}
Also read this thread which has an excellent explanation - Rule of Three