Can anyone help me with this question please? For background information, I have three classes, Account.h
with Account.cpp
, Node.h
with Node.cpp
, LinkedList.h
with Linkedlist.cpp
, and demo.cpp
that contains int main()
. All of the current functions are working except for printing out the linkedlist, which is the basis of my question.
The question specifically says:
Implement a non-member overloaded
operator <<
function, that uses theoperator <<
fromAccount
, to allow you to perform an operation like:
cout << MyLinkedList << endl;
I copied specific parts of my code related to this question from LinkedList.cpp
and Account.cpp
because it will be too long if I paste it all here.
Code from LinkedList.cpp
with overloaded operator <<
function "not yet working" is as shown below: Please note value_type
is typedef for Account
.
#include "LinkedList.h"
LinkedList::value_type LinkedList::getCurrent() const {
if (current != NULL) {
return current->getData();
} else {
return value_type();
}
}
ostream& operator << (ostream& out, const LinkedList& list) { // not working, compile error!
value_type current = getCurrent();
while (current != NULL) {
out << "(" << acc.getName() << "," << acc.balance() << ")" << endl;
}
return out;
}
Code from Account.cpp
is as shown below:
ostream& operator << (ostream& out, const Account& acc)
{
out << "(" << acc.getName() << "," << acc.balance() << ")" << endl;
return out;
}
These are the class declarations for my node.h file:
#ifndef TEKAAI_NODE
#define TEKAAI_NODE
#include "Account.h"
class Node
{
public:
// members that are externally visible
// Below are Member functions
// specifying value_type to Account using typedef
typedef Account value_type;
// Default constructor
Node();
// Parameter Constructors
Node(const value_type& initial_data, Node* initial_link);
~Node(); //destructor
void setNext(Node* n);
void setPrevious(Node* p);
Node* getNext() const;
Node* getPrevious() const;
// the data getters and setters
// Pre-condition: Current has been initialized
// Post-condition: set data
void setData(const value_type& i);
// Pre-condition: Data has been initialized
// Post-condition: returns stored data
value_type getData() const;
private:
value_type data; //the data held by the node
Node* next; //a pointer to the next node
Node* previous; //a pointer to the previous node
};
#endif
These are the class declarations in my LinkedList.h file:
#ifndef TEKAAI_LINKEDLIST_H
#define TEKAAI_LINKEDLIST_H
#include "Account.h"
#include "Node.h"
#include <iostream>
class LinkedList
{
public:
typedef Account value_type;
// Members that are externally visible
// These are Member functions
// Constructors
LinkedList();
// Destructor
~LinkedList();
void addToHead(const value_type& account);
void addToTail(const value_type& account);
void addCurrent(const value_type& account);
value_type removeFromHead();
value_type removeFromTail();
value_type removeFromCurrent();
// Pre-condition: LinkedList contains nodes
// Post-condition: moves current to the head
void start();
// Pre-condition: LinkedList contains nodes
// Post-condition: moves current to the tail
void end();
// Pre-condition: LinkedList contains nodes
// Post-condition: moves current one node to the right
void forward();
// Pre-condition: LinkedList contains nodes
// Post-condition: moves current one node to the left
void back();
// Pre-condition: LinkedList contains nodes
// Post-condition: returns the value of data account stored
// in current node
value_type getCurrent() const;
// Pre-condition: LinkedList is initialized, containing
// nodes
// Post-condition: returns the length of the list
int length();
private:
Node* head;
Node* tail;
Node* current;
};
ostream& operator << (ostream& out, const LinkedList& list);
#endif
As you can see in LinkedList class declarations above,I have to work with them to try and print out my linkedlist. I would like to hear your thoughts if it is possible to print my linkedlist using one of the above functions while also using the overloaded << operator from Account as the question specified.
Thanks.
PLUS NOTE: Just to let you know that I can get to print my linkedlist using the function 'Node* getHead() const;' which returns head in overloading the << operator, but I was just looking for help if it is possible to print linkedlist without using the getHead() function. I guess our lecturer was just messing with us, trying to make us lose our minds with his lab activity.
First, your operator<<
's should be taking their 2nd parameters by const reference, not by value, eg:
ostream& operator << (ostream& out, const Account& acc)
ostream& operator << (ostream& out, const LinkedList& list)
Second, yes, it is possible to use the Account
operator inside the LinkedList
operator. You need something equivalent to the following (since you didn't provide full class declarations):
ostream& operator << (ostream& out, const LinkedList& list) {
LinkedList::Node *cur = list.getFirst();
while (cur != NULL) {
out << cur->getData();
cur = cur->getNext();
}
return out;
}
UPDATE: now that you have posted your LinkedList
class declaration, I see that it does not offer anything like a getFirst()
method. It has start()
and forward()
methods for iterating the list, but there is no method to indicate when the iteration has reached the end of the list.
So, you have a few options:
getCurrent()
is safe to call:class LinkedList
{
public:
...
bool hasCurrent() const;
value_type getCurrent() const;
...
};
bool LinkedList::hasCurrent() const {
return (current != NULL);
}
LinkedList::value_type LinkedList::getCurrent() const {
return current->getData();
}
ostream& operator << (ostream& out, LinkedList& list) {
list.start();
while (list.hasCurrent()) {
out << list.getCurrent();
list.forward();
}
return out;
}
getCurrent()
method to return the Account
object by pointer instead of by value so that it can return a NULL
pointer when the iteration is at the end of the list:class Node
{
public:
...
value_type& getData();
...
};
LinkedList::value_type* LinkedList::getCurrent() {
if (current != NULL) {
return &(current->getData());
} else {
return NULL;
}
}
ostream& operator << (ostream& out, LinkedList& list) {
Account *cur;
list.start();
while ((cur = list.getCurrent()) != NULL) {
out << *cur;
list.forward();
}
return out;
}
LinkedList
operator be a friend
of the LinkedList
class so it can access the private head
member directly:class LinkedList
{
public:
...
friend ostream& operator << (ostream& out, const LinkedList& list);
...
private:
Node* head;
...
};
ostream& operator << (ostream& out, const LinkedList& list);
ostream& operator << (ostream& out, const LinkedList& list) {
Node *cur = list.head;
while (cur != NULL) {
out << cur->getData();
cur = cur->getNext();
}
return out;
}