C++ : cannot create node pointer inside ostream& operator << - c++

I'm using C++ to implement LinkedList, other functions and operators I can create Node* just fine. However when I get to this operator "ostream& operator << (ostream& out, const LinkedList& list)" (output the list), I can not create a temporary inside the operator, can anyone tell me what causes the error and how to fix it?
Here is my LinkedList.h
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include <iostream>
using namespace std;
class LinkedList {
typedef struct Node{
int data;
Node* next;
bool operator < (const Node& node) const {
return this->data < node.data;
}
bool operator <= (const Node& node) const {
return this->data <= node.data;
}
bool operator > (const Node& node) const {
return this->data > node.data;
}
bool operator >= (const Node& node) const {
return this->data >= node.data;
}
friend ostream& operator << (ostream& out, const LinkedList& list);
friend istream& operator >> (istream& in, const LinkedList& list);
} * nodePtr;
public:
nodePtr head;
nodePtr curr;
LinkedList();
// functions
void push_front(int);
void push_back(int);
int pop_front();
int pop_back();
int size();
bool contains(int);
void print();
void clear();
// overload
LinkedList& operator =(const LinkedList& list);
bool operator !=(const LinkedList& list) const;
LinkedList operator +(const int v) const;
LinkedList operator +(const LinkedList& list) const;
LinkedList operator - (const int v) const;
friend ostream& operator << (ostream& out, const LinkedList& list);
friend istream& operator >> (istream& in, const LinkedList& list);
};
#endif /* LINKEDLIST_H */
in my LinkedList.cpp:
ostream& operator << (ostream& out, const LinkedList& list) {
nodePtr temp = list.head; <----------------- **Unable to resolve identifier nodePtr**
}
I can create Node* (nodePtr) on my other functions just fine.

nodePtr is defined inside LinkedList, it need to be qualified. Change
nodePtr temp = list.head;
to
LinkedList::nodePtr temp = list.head;

Related

Overloading output stream operator: no operator "<<" matches these operands

I recently asked the question: Is ostream& operator<< better practice in a class than using std::cout? and got an excellent answer.
When I tried to implement the solution I got errors:
no operator "<<" matches these operands
and
binary '<<': no operator found which takes a right-hand operand of type 'LinkedList' (or there is no acceptable conversion)
The simplest solution in this case would be to add a std::ostream parameter to your display() method, eg:
LinkedList.h
#include <iostream>
#pragma once
class LinkedList
{
struct Node {
int data = 0;
Node* prev = nullptr;
Node* next = nullptr;
};
private:
Node* m_head;
public:
// CONSTRUCTOR
LinkedList();
// DESTRUCTOR
~LinkedList();
void display(std::ostream& out) const;
};
LinkedList.cpp
#include <iostream>
#include "LinkedList.h"
LinkedList::LinkedList() {
m_head = nullptr;
}
void LinkedList::display(std::ostream &out) const {
Node* curr = m_head;
while (curr) {
out << curr->data << " -> ";
curr = curr->next;
}
out << std::endl;
}
std::ostream& operator<<(std::ostream &out, const LinkedList &list) {
list.display(out);
return out;
}
Main.cpp (generates error)
#include <iostream>
#include "LinkedList.h"
int main() {
LinkedList list;
std::cout << list;
}
I got some help with this question but it was swiftly deleted...
Essentially the problem is that std::ostream& operator<<(std::ostream &out, const LinkedList &list) is not correctly advertised.
We need to add friend std::ostream& operator<<(std::ostream& output, const SortedList& list); to the LinkedList.h file within the LinkedList class
LinkedList.h
#include <iostream>
#pragma once
class LinkedList
{
struct Node {
int data = 0;
Node* next = nullptr;
};
private:
Node* m_head;
public:
// CONSTRUCTOR
LinkedList();
// DESTRUCTOR
~LinkedList();
void display(std::ostream& out) const;
friend std::ostream& operator<<(std::ostream& output, const LinkedList& list);
};

How to call operator= from class 'X' into class 'Y' with its own operator= function?

Can someone help me figure out how to call an operator overloaded function from one class into another class when both classes have functions titled operator=?
I have a class called "Deque" that represents a double ended queue. This double ended queue is made using linked nodes that I call "DequeNode". Each "DequeNode" has the private data members of a next and prev pointer as well as a variable to store a value/item. I have tested the deque.cpp and deque.h files with a driver I wrote and they are working as intended.
I want to make a class called LongInt, that presents an integer. A LongInt is supposed to represent an integer value that cannot be stored in an int variable. A LongInt has three private data members, a Deque object called digits, a bool, called negative, to determine if the value being stored in a LongInt is negative or positive, and a function to remove extra 0's at the front of the LongInt object.
I am having trouble writing the overloaded assignment operator (operator=) for the LongInt class (located in longint.cpp). The assignment operator for the LongInt class should take whatever is on the RHS of the '=' sign and make a copy of that to the current object/LHS of the '=' sign. To do this, I need to find a way to copy the Deque object of the RHS of the '=' to the LHS. To do this, in the operator= function in longint.cpp, I want to use the operator= function from the deque.cpp file to set the digits object of the item on the LHS of the operator= function of longint.cpp. However, I am not sure how to do this and that is my main ask for help with. Can someone help me out with this?
To maybe put this another way, inside the operator= function in longint.cpp, I want to use the "Deque(const Deque &rhs);" constructor from the Deque class to make a new Deque object. I want to pass in the Deque object from the LongInt object being passed into the operator= function in longint.cpp to the constructor from the Deque.cpp class.
Below is the code for the files: deque.h, deque.cpp, longint.h, and longint.cpp.
deque.h:
#ifndef DEQUE_H
#define DEQUE_H
#include <iostream>
using namespace std;
template <class Object>
class Deque {
public:
Deque(); // the constructor
Deque(const Deque &rhs); // the copy constructor
~Deque(); // the destructor
bool isEmpty() const; // checks if a deque is empty.
int size() const; // retrieves # deque nodes
const Object &getFront() const; // retrieve the front node
const Object &getBack() const; // retrieve the tail node
void clear(); // clean up all deque entries.
void addFront(const Object &obj); // add a new node to the front
void addBack(const Object &obj); // add a new node to the tail
Object removeFront(); // remove the front node
Object removeBack(); // remove the tail node
const Deque &operator=(const Deque &rhs); // assignment
private:
struct DequeNode { // a deque node
Object item;
DequeNode *next;
DequeNode *prev;
};
DequeNode *front;
DequeNode *back;
};
#include "deque.cpp"
#endif
deque.cpp:
template <class Object>
Deque<Object>::Deque() { // the constructor
front = back = NULL;
}
template <class Object>
Deque<Object>::Deque(const Deque &rhs) { // the copy constructor
front = back = NULL;
*this = rhs;
}
template <class Object>
Deque<Object>::~Deque() { // the destructor
clear();
}
template <class Object>
bool Deque<Object>::isEmpty() const { // check if a deque is empty
return front == NULL;
}
template <class Object>
int Deque<Object>::size() const { // retrieves # deque nodes
int i = 0;
for ( DequeNode *ptr = front; ptr != NULL; ptr = ptr->next ) // traverse que
++i;
return i;
}
template <class Object>
const Object &Deque<Object>::getFront() const { // retrieve the front node
if (isEmpty())
throw "empty queue";
return front->item;
}
template <class Object>
const Object &Deque<Object>::getBack() const { // retrieve the tail node
if (isEmpty())
throw "empty queue";
return back->item;
}
template <class Object>
void Deque<Object>::clear() { // clean up all entries.
while (!isEmpty()) // dequeue till the queue gets empty.
removeFront();
}
// add a new node to front
template <class Object>
void Deque<Object>::addFront(const Object &obj){
DequeNode *new_node = new DequeNode;
new_node->prev = NULL;
new_node->next = front;
new_node->item = obj;
//Checking for the edge case where we have no nodes
if (front == NULL){ //If we have no nodes, both front and back get set to the only node.
back = new_node;
front = new_node;
}
else{ //Else, everything else is handled by this
front->prev = new_node;
front = new_node;
}
}
// add a new node to tail
template <class Object>
void Deque<Object>::addBack(const Object &obj){
DequeNode *new_node = new DequeNode;
new_node->prev = back;
new_node->next = NULL;
new_node->item = obj;
//Checking for the edge case where we have no nodes
if (back==NULL){ //If we have no nodes, both front and back get set to the only node.
front = new_node;
back = new_node;
}
else{ //Else, everything else is handled by this
back->next = new_node;
back = new_node;
}
}
template <class Object>
Object Deque<Object>::removeFront(){ //remove the front node
DequeNode *pos = front; //create a pointer to keep track of node to be deleted
//Need to find a way to access the item being help at the location of front.
Object removedItem = pos->item;
if(front == back){ //Case for when there is only a single node left in the Queue.
front = NULL;
back = NULL;
}
else{ //All other cases should fall into this else statement
front->next->prev = NULL;
//front->next = NULL;
front = front->next;
}
delete pos;
return removedItem;
}
template <class Object>
Object Deque<Object>::removeBack(){ // remove the tail node
DequeNode *pos = back; //create a pointer to keep track of node to be deleted
//Need to find a way to access the item being help at the location of front.
Object removedItem = pos->item;
if(front==back){
front = NULL;
back = NULL;
}
else{
back->prev->next = NULL;
back = back->prev;
}
delete pos;
return removedItem;
}
template <class Object>
const Deque<Object> &Deque<Object>::operator=(const Deque &rhs) { // assign
if (this != &rhs) { // avoid self assignment
clear();
for (DequeNode *rptr = rhs.front; rptr != NULL; rptr = rptr->next)
addBack(rptr->item);
}
return *this;
}
longint.h:
#ifndef LONGINT_H
#define LONGINT_H
#include <iostream>
#include "deque.h"
using namespace std;
class LongInt {
friend istream &operator>>(istream &in, LongInt &rhs);
friend ostream &operator<<(ostream &out, const LongInt &rhs);
public:
// Constructors
LongInt(const string str);
LongInt(const LongInt &rhs);
LongInt();
// Destructor
~LongInt();
// Arithmetic binary operators
LongInt operator+(const LongInt &rhs) const;
LongInt operator-(const LongInt &rhs) const;
// assignment operators
const LongInt &operator=(const LongInt &rhs);
// Logical binary operators
bool operator< (const LongInt & rhs) const;
bool operator<=(const LongInt & rhs) const;
bool operator> (const LongInt & rhs) const;
bool operator>=(const LongInt & rhs) const;
bool operator==(const LongInt & rhs) const;
bool operator!=(const LongInt & rhs) const;
private:
Deque<char> digits;
bool negative;
void remove0s();
};
#endif
longint.cpp:
#include "longint.h"
//istream &operator>>(istream &in, LongInt &rhs){
//return in;
//}
ostream &operator<<(ostream &out, const LongInt &rhs){
//LongInt tmp = rhs;
cout << "entering the operator<<" << endl;
cout <<"get front in main: " << rhs.digits.getFront() << endl;
cout << "get back in main: " << rhs.digits.getBack() << endl;
return out;
}
//Constructors
//Here I want to go through the entire string and add all the values to the string in the correct order in the string.
LongInt::LongInt(const string str){
cout << "constructor w/ str input" << endl;
int i = 0;
while (str[i]){
digits.addBack(str[i]);
i++;
}
}
//LongInt::LongInt(const LongInt &rhs)
LongInt::LongInt(){
cout << "constructor w/no parameters" << endl;
digits.addBack('0');
cout <<"getBack of default constructor: " << digits.getBack() << endl;
cout << "size of current digits deque: " << digits.size() << endl;
negative = false;
}
// Destructor
LongInt::~LongInt(){
digits.clear();
}
// Arithmetic binary operators
//LongInt operator+(const LongInt &rhs) const;
//LongInt operator-(const LongInt &rhs) const;
// assignment operators
const LongInt & LongInt::operator=(const LongInt &rhs){
this->negative = rhs.negative; //Set the new LongInt sign to the RHS sign.
this->digits = Deque<char>(rhs.digits); //How do I call the deque classes operator= function?
return *this;
}
// Logical binary operators
//bool operator< (const LongInt & rhs) const;
//bool operator<=(const LongInt & rhs) const;
//bool operator> (const LongInt & rhs) const;
//bool operator>=(const LongInt & rhs) const;
//bool operator==(const LongInt & rhs) const;
//bool operator!=(const LongInt & rhs) const;

Problem with template type T not being understood by my operator overloading friend function

This is a continuation of my last post. I'm getting this error now:
Error C2679 binary '<<': no operator found which takes a right-hand operand of type 'T'
This is happening because of a friend operator overload function not understanding the type T being overloaded for some reason.
#include <iostream>
#include <fstream>
#include <string>
template <typename T>
class LL
{
struct Node
{
T mData;
Node *mNext;
Node();
Node(T data);
};
private:
Node *mHead, *mTail;
int mCount;
public:
LL();
~LL();
bool insert(T data);
bool isExist(T data);
bool remove(T data);
void showLinkedList();
void clear();
int getCount() const;
bool isEmpty();
friend std::ofstream& operator<<(std::ofstream& output, const LL& obj)
{
Node* tmp;
if (obj.mHead != NULL)
{
tmp = obj.mHead;
while (tmp != NULL)
{
output << tmp->mData << std::endl; // "tmp->mData" is where the error is
tmp = tmp->mNext;
}
}
return output;
}
};
Your stream operator should be defined with std::ostream not std::ofstream, e.g.:
friend std::ostream& operator<<(std::ostream& output, const LL& obj)

error C2244 unable to match function definition to an existing declaration in cpp /// operator overloading

I am trying to overload =+ operator. there are two of it. One for the linkedlist+=linkedlist, other for the linkedlist+=templated type. But vs gives me an error.
template <class T>
const DList<T>& DList<T>::operator += (const DList & rhs)
{
Node<T> temp=head;
while(temp->next!=NULL)
{
temp=temp->next;
}
rhs.head->prev=temp;
temp->next=rhs.head;
return *this;
}
template <class T>
DList<T>& DList<T>::operator += (T n)
{
Node<T> * temp= new Node<T>(n, NULL, head);
head=temp;
return *this;
}
Here the entire header:
#ifndef _DList_H
#define _DList_H
template <class T>
struct Node
{
T val;
Node<T>* next;
Node<T>* prev;
Node(T el, Node<T>* p=NULL, Node<T>* n=NULL ): val(el), prev(p), next(n)
{};
};
template <class T>
class DList
{
private:
Node<T>* head;
int size;
public:
const DList & DList::operator += (const DList & rhs);
DList();
DList(const DList&);
~DList();
bool isEmpty();
void printList() const;
void addToBeginning(T n);
void deleteList ();
const DList<T> & DList::operator = (const DList & rhs);
const DList<T> & DList::operator += (T);
const DList<T> & DList::operator -= (T);
bool DList<T>::operator < (const DList & rhs);
bool DList<T>::operator > (const DList & rhs);
bool DList<T>::operator == (const DList & rhs);
Node<T> * createClone () const;
};
#include "DList.cpp"
#endif
Btw, it's my first question. I hope that asked it clearly and used the format correctly.
The full error message:
Error 1 error C2244: 'DList::+=' : unable to match function definition to an existing declaration
+= operator used like this:
list4 += list1 += list2;
list1 -= 5;
list1 -= 6;
If you are using templates, you cannot separate function defintion from declaration.
The DList:: prefix may not be in the function declaration within the class body.
You should not inculde cpp files. These files should include header files to make declarations available for the compiler.

When using assignment operator overloading, the new object isn't accessible outside of operator=()

I have an implementation of a Queue which requires writing an assignment operator overload.
Queue& Queue::operator= (const Queue& rhs){
if(this->head == rhs.head) return *this;
Queue * newlist;
if(rhs.head == NULL){
// copying over an empty list will clear it.
this->clear();
return * newlist;
}
newlist = new Queue(rhs);
cout << "made new queue" << endl;
cout << "new list : " << * newlist << endl;
return * newlist;
}
The problem I'm running into is that when I leave this function, the contents of newlist are no longer accessible. How is an operator=() function supposed to look?
EDIT:
queue.h:
class Queue : public LinkedList {
protected:
unsigned maxSize;
public:
Queue(unsigned N = -1);
Queue(const Collection& collection, unsigned N = -1);
~Queue();
Queue(const Queue& obj);
Queue& operator= (const Queue& rhs);
friend std::ostream& operator<<(std::ostream& ostream, const Queue &rhs);
bool add(myType element);
myType element();
bool offer(myType element);
myType peek();
myType poll();
myType remove();
};
How is an operator=() function supposed to look?
An operator= is supposed to modify the internal object (*this) with the values of rhs and then literally return (*this).