Please solve in C++ Overloading useful operators 1. Implement the subscript ([])
ID: 3727427 • Letter: P
Question
Please solve in C++
Overloading useful operators
1. Implement the subscript ([]) operator as a member function of the List class. This takes an integer subscript as a parameter and returns the data pointer of the element at that position in the List object.
2. Implement the stream insertion (<<) operator of the List class. To make your code more consistent, implement the same operator in the Student class so that you can use it from the List operator. Both operators can replace the existing print functions.
----------------------------list.cc--------------------------------------------
#include <iostream>
using namespace std;
#include "List.h"
List::List() : head(0), tail(0) { }
List::~List()
{
cleanup();
}
// Adds a student to the front of the list
void List::addFront(Student* newStu)
{
Node* tmpNode = new Node;
tmpNode->data = newStu;
tmpNode->prev = 0;
tmpNode->next = 0;
if (head == 0) {
head = tmpNode;
tail = tmpNode;
return;
}
tmpNode->next = head;
head->prev = tmpNode;
head = tmpNode;
}
// Adds a student in alphabetical order
void List::addAlpha(Student* newStu)
{
Node* tmpNode = new Node;
tmpNode->data = newStu;
tmpNode->next = 0;
tmpNode->prev = 0;
if (head == 0) {
head = tmpNode;
tail = tmpNode;
return;
}
Node *currNode, *prevNode;
prevNode = 0;
currNode = head;
while (currNode != 0) {
if (currNode->data->getName() > tmpNode->data->getName())
break;
prevNode = currNode;
currNode = currNode->next;
}
if (currNode == head) { // add to first position
currNode->prev = tmpNode;
tmpNode->next = currNode;
head = tmpNode;
}
else if (currNode == 0) { // add to last position
prevNode->next = tmpNode;
tmpNode->prev = prevNode;
tail = tmpNode;
}
else { // add in the middle
tmpNode->next = currNode;
tmpNode->prev = prevNode;
prevNode->next = tmpNode;
currNode->prev = tmpNode;
}
}
void List::print() const
{
Node* currNode = head;
if (currNode == 0) return;
do {
currNode->data->print();
currNode = currNode->next;
} while (currNode != 0);
}
void List::printBack() const
{
Node* currNode = tail;
if (currNode == 0) return;
do {
currNode->data->print();
currNode = currNode->prev;
} while (currNode != 0);
}
void List::cleanupData()
{
Node *currNode = head;
while (currNode != 0) {
delete currNode->data;
currNode = currNode->next;
}
}
void List::cleanup()
{
Node *currNode, *nextNode;
currNode = head;
while (currNode != 0) {
nextNode = currNode->next;
delete currNode;
currNode = nextNode;
}
head = tail = 0;
}
----------------------------list.h--------------------------------------------
#ifndef LIST_H
#define LIST_H
#include "Student.h"
class List
{
class Node
{
friend class List;
private:
Student* data;
Node* prev;
Node* next;
};
public:
List();
~List();
void addFront(Student*);
void addAlpha(Student*);
void cleanupData();
void print() const;
void printBack() const;
private:
Node* head;
Node* tail;
void cleanup();
};
#endif
----------------------------main.cc--------------------------------------------
#include <iostream>
using namespace std;
#include <string>
#include <fstream>
#include <cstdlib>
#include "Student.h"
#include "List.h"
int main()
{
List list1, list2;
Student* stuPtr;
string name, number;
ifstream infile("stu.txt", ios::in);
if (!infile) {
cout<<"could not open file"<<endl;
exit(1);
}
while (infile >> number >> name) {
stuPtr = new Student(number, name);
list1.addFront(stuPtr);
list2.addAlpha(stuPtr);
}
cout << "ADD FRONT FORWARD" << endl;
list1.print();
cout << "ADD FRONT BACKWARD" << endl;
list1.printBack();
cout << "ADD ALPHA FORWARD" << endl;
list2.print();;
cout << "ADD ALPHA BACKWARD" << endl;
list2.printBack();;
list1.cleanupData();
}
----------------------------student.cc--------------------------------------------
#include <iostream>
using namespace std;
#include <string>
#include "Student.h"
Student::Student(string nu, string na)
: number(nu), name(na) { }
Student::~Student() { }
string Student::getName() const { return name; }
void Student::setName(string n) { name = n; }
void Student::print() const
{
cout<<"Student: "<<number<<" "<<name<<endl;
}
----------------------------student.h--------------------------------------------
#ifndef STUDENT_H
#define STUDENT_H
class Student
{
public:
Student(string="000000000", string="");
~Student();
string getName() const;
void setName(string);
void print() const;
private:
const string number;
string name;
};
#endif
-----------------stu.txt--------------------------------
100567899 Matilda
100234555 Joe
100456777 Timmy
100333222 Clayton
100999888 Harold
Explanation / Answer
//Code is explained in comments:
---------------------------------------------------List.h--------------------------------
#ifndef LIST_H
#define LIST_H
#include "Student.h"
class Node
{
friend class List;
public:
Student* data;
Node* prev;
Node* next;
};
class List
{
public:
List();
~List();
void addFront(Student*);
void addAlpha(Student*);
void cleanupData();
void print() const;
void printBack() const;
Node* operator [](int index);
friend ostream &operator <<(ostream &out,const List & list);
private:
Node* head;
Node* tail;
void cleanup();
};
-------------------List.cpp------------------------------
#include <iostream>
#include "List.h"
using namespace std;
/*The operators ‘<<' and '<<' are called like 'cout << ob1' and 'cin << ob1'. So if we want to make them a member method, then they must be made members of ostream and istream classes, which is not a good option most of the time. Therefore, these operators are overloaded as global functions with two parameters, cout and object of user defined class.*/
ostream & operator <<(ostream &out,const List &list){
Node* currNode = list.head;
do {
out<<currNode->data->getName()<<currNode->data->getNumber()<<endl;
currNode = currNode->next;
} while (currNode != 0);
}
List::List() : head(0), tail(0) { }
List::~List()
{
cleanup();
}
//Oveloading subsrcipt operator []
Node* List::operator [](int index){
Node* tmpNode = new Node; //took new node to
int counter=0; //initialised counter=0
if(head==NULL){
return NULL;
}
tmpNode=head; //store head in tmpNode
while(counter <=index){ //loop untill counter <= index
tmpNode=head->next; //make tmpNode =head->next every iteration
counter++;
}
if(counter !=index)//if counter is less than index,return NULL
{
cout<<"There is no such index value"<<endl;
return NULL;
}
else{
return tmpNode;
}
}
// Adds a student to the front of the list
void List::addFront(Student* newStu)
{
Node* tmpNode = new Node;
tmpNode->data = newStu;
tmpNode->prev = 0;
tmpNode->next = 0;
if (head == 0) {
head = tmpNode;
tail = tmpNode;
return;
}
tmpNode->next = head;
head->prev = tmpNode;
head = tmpNode;
}
// Adds a student in alphabetical order
void List::addAlpha(Student* newStu)
{
Node* tmpNode = new Node;
tmpNode->data = newStu;
tmpNode->next = 0;
tmpNode->prev = 0;
if (head == 0) {
head = tmpNode;
tail = tmpNode;
return;
}
Node *currNode, *prevNode;
prevNode = 0;
currNode = head;
while (currNode != 0) {
if (currNode->data->getName() > tmpNode->data->getName())
break;
prevNode = currNode;
currNode = currNode->next;
}
if (currNode == head) { // add to first position
currNode->prev = tmpNode;
tmpNode->next = currNode;
head = tmpNode;
}
else if (currNode == 0) { // add to last position
prevNode->next = tmpNode;
tmpNode->prev = prevNode;
tail = tmpNode;
}
else { // add in the middle
tmpNode->next = currNode;
tmpNode->prev = prevNode;
prevNode->next = tmpNode;
currNode->prev = tmpNode;
}
}
void List::print() const
{
Node* currNode = head;
if (currNode == 0) return;
do {
currNode->data->print();
currNode = currNode->next;
} while (currNode != 0);
}
void List::printBack() const
{
Node* currNode = tail;
if (currNode == 0) return;
do {
currNode->data->print();
currNode = currNode->prev;
} while (currNode != 0);
}
void List::cleanupData()
{
Node *currNode = head;
while (currNode != 0) {
delete currNode->data;
currNode = currNode->next;
}
}
void List::cleanup()
{
Node *currNode, *nextNode;
currNode = head;
while (currNode != 0) {
nextNode = currNode->next;
delete currNode;
currNode = nextNode;
}
head = tail = 0;
}
-----------------------student.h----------------------
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <string>
class Student
{
public:
Student(string="000000000", string="");
~Student();
string getName() const;
string getNumber()const;
void setName(string);
void print() const;
friend ostream &operator <<(ostream &out,const Student & student);
private:
const string number;
string name;
};
-------------------------------------student.cpp---------------------------
#include <iostream>
using namespace std;
#include <string>
#include "Student.h"
ostream & operator<<(ostream &out,const Student &student){
out<<"Student: Number: "<<student.number<<" Student Name:"<<student.name<<endl;
}
/*The operators ‘<<' and '<<' are called like 'cout << ob1' and 'cin << ob1'. So if we want to make them a member method, then they must be made members of ostream and istream classes, which is not a good option most of the time. Therefore,
these operators are overloaded as global functions with two parameters, cout and object of user defined class.*/
Student::Student(string nu, string na)
: number(nu), name(na) { }
Student::~Student() { }
string Student::getName() const { return name; }
string Student::getNumber()const{return number;}
void Student::setName(string n) { name = n; }
void Student::print() const
{
cout<<"Student: "<<number<<" "<<name<<endl;
}
------------------------------------list.h---------------------------------------------------------
-----------------main.cpp-----------------------------
#include <iostream>
using namespace std;
#include <string>
#include <fstream>
#include <cstdlib>
#include "Student.h"
#include "List.h"
int main()
{
List list1, list2;
Student* stuPtr;
string name, number;
ifstream infile("stu.txt", ios::in);
if (!infile) {
cout<<"could not open file"<<endl;
exit(1);
}
cout<<"----------------------Using operator << to print student object---------------------"<<endl;
while (infile >> number >> name) {
stuPtr = new Student(number, name);
cout<<*stuPtr;
list1.addFront(stuPtr);
list2.addAlpha(stuPtr);
}
//Here assigned operator [] to Node *node by creating new node
Node *node=list1[3];
cout << "ADD FRONT FORWARD" << endl;
list1.print();
cout<<"-----------------------------Using << operator to print list1--------------------"<<endl;
cout<<list1;
cout << "ADD FRONT BACKWARD" << endl;
list1.printBack();
cout << "ADD ALPHA FORWARD" << endl;
list2.print();
cout<<"----------------------------------Using << operator to print list2 ------------------------------"<<endl;
cout<<list2;
cout << "ADD ALPHA BACKWARD" << endl;
list2.printBack();;
list1.cleanupData();
}
//OUTPUT:
ramcharan@ramcharan-VirtualBox:~/Downloads/C++$ g++ student_list.cpp -o studentlist
ramcharan@ramcharan-VirtualBox:~/Downloads/C++$ ./studentlist
----------------------Using operator << to print student object---------------------
Student: Number: 100567899 Student Name:Matilda
Student: Number: 100234555 Student Name:Joe
Student: Number: 100456777 Student Name:Timmy
Student: Number: 100333222 Student Name:Clayton
Student: Number: 100999888 Student Name:Harold
There is no such index value
ADD FRONT FORWARD
Student: 100999888 Harold
Student: 100333222 Clayton
Student: 100456777 Timmy
Student: 100234555 Joe
Student: 100567899 Matilda
-----------------------------Using << operator to print list1--------------------
Harold100999888
Clayton100333222
Timmy100456777
Joe100234555
Matilda100567899
ADD FRONT BACKWARD
Student: 100567899 Matilda
Student: 100234555 Joe
Student: 100456777 Timmy
Student: 100333222 Clayton
Student: 100999888 Harold
ADD ALPHA FORWARD
Student: 100333222 Clayton
Student: 100999888 Harold
Student: 100234555 Joe
Student: 100567899 Matilda
Student: 100456777 Timmy
----------------------------------Using << operator to print list2 ------------------------------
Clayton100333222
Harold100999888
Joe100234555
Matilda100567899
Timmy100456777
ADD ALPHA BACKWARD
Student: 100456777 Timmy
Student: 100567899 Matilda
Student: 100234555 Joe
Student: 100999888 Harold
Student: 100333222 Clayton