In: Computer Science
You are required to come up with a single header file (IntList.h) that declares and implements the IntNode class (just copy it exactly as it is below) as well as declares the IntList Class interface only. You are also required to come up with a separate implementation file (IntList.cpp) that implements the member functions of the IntList class. While developing your IntList class you must write your own test harness (within a file named main.cpp). Never implement more than 1 or 2 member functions without fulling testing them with your own test harness.
IntNode struct
I am providing the IntNode class you are required to use. Place this class definition within the IntList.h file exactly as is. Make sure you place it above the definition of your IntList class. Notice that you will not code an implementation file for the IntNode class. The IntNode constructor has been defined inline (within the class declaration). Do not write any other functions for the IntNode class. Use as is.
struct IntNode { int data; IntNode *next; IntNode(int data) : data(data), next(0) {} };
IntList class
Encapsulated (Private) Data Fields
head: IntNode *
tail: IntNode *
Public Interface (Public Member Functions)
IntList(): Initializes an empty list.
~IntList(): Deallocates all remaining dynamically allocated memory (all remaining IntNodes).
void display() const: Displays to a single line all of the int values stored in the list, each separated by a space. This function does NOToutput a newline or space at the end.
void push_front(int value): Inserts a data value (within a new node) at the front end of the list.
void pop_front(): Removes the value (actually removes the node that contains the value) at the front end of the list. Does nothing if the list is already empty.
bool empty() const: Returns true if the list does not store any data values (does not have any nodes), otherwise returns false.
main.cpp test harness for lab
Use this main.cpp file for testing your IntList.
#include <iostream> using namespace std; #include "IntList.h" int main() { //tests constructor, destructor, push_front, pop_front, display { cout << "\nlist1 constructor called"; IntList list1; cout << "\npushfront 10"; list1.push_front(10); cout << "\npushfront 20"; list1.push_front(20); cout << "\npushfront 30"; list1.push_front(30); cout << "\nlist1: "; list1.display(); cout << "\npop"; list1.pop_front(); cout << "\nlist1: "; list1.display(); cout << "\npop"; list1.pop_front(); cout << "\nlist1: "; list1.display(); cout << "\npop"; list1.pop_front(); cout << "\nlist1: "; list1.display(); cout << endl; } cout << "list1 destructor called" << endl; return 0; }
main.cpp
#include <iostream>
using namespace std;
#include "IntList.h"
int main() {
//tests constructor, destructor, push_front, pop_front,
display
cout << "\nlist1 constructor called";
IntList list1;
cout << "\npushfront 10";
list1.push_front(10);
cout << "\npushfront 20";
list1.push_front(20);
cout << "\npushfront 30";
list1.push_front(30);
cout << "\nlist1: ";
list1.display();
cout << "\npop";
list1.pop_front();
cout << "\nlist1: ";
list1.display();
cout << "\npop";
list1.pop_front();
cout << "\nlist1: ";
list1.display();
cout << "\npop";
list1.pop_front();
cout << "\nlist1: ";
list1.display();
cout << endl;
cout << "list1 destructor called" << endl;
return 0;
}
IntList.cpp
#include <iostream>
#include "IntList.h"
using namespace std;
IntList::IntList() : head(NULL), tail(NULL) { }
IntList::~IntList() {
while(!empty()){
pop_front();
}
}
void IntList::push_front(int value) {
/*Creates a temporary pointer of type IntNode, assigning a memory
address (block of memory)
to temp_ptr of type IntNode and then initializing with a
constructor. */
IntNode* temp_ptr = new IntNode(value);
/*Then we assign the current address of head (if just empty list,
this is NULL) to the
dereferenced temporary pointer's next memory address
*/
(*temp_ptr).next = this->head;
/*Assign the memory address of temporary pointer (which points to
the newly created block of memory) to head. */
this->head = temp_ptr;
return;
}
void IntList::display() const {
/* If empty list, exit out of display function */
if(empty()) {
return;
}
//Since the list is not empty, print the data which the
dereferenced head points to
cout << (*head).data;
//Initialize a new pointer, which is assigned to the next pointer
in the linked list
IntNode* plc_ptr = (*head).next;
// Create a while loop that checks whether the pointer points to
anything.
// This checks to see whether it is the end of the linked
list
while(plc_ptr != NULL) {
// Prints the dereferenced pointers data
cout << " " <<
(*plc_ptr).data;
/*Updates the memory address which the temporary pointer points
to,
going through the list each time it goes through the while loop
*/
plc_ptr = (*plc_ptr).next;
}
return;
}
bool IntList::empty() const {
//The linked list is empty if the head doesn't point to any memory
addres/is NULL
if(head == NULL) {
return true;
}
return false;
}
void IntList::pop_front() {
//First check to see if the linked list is empty/if there is a
first item that needs to be deleted
if(empty()) {
return;
}
//Set a temporary pointer to the next of the first item, which is
the memory address of the second item
IntNode* temp_ptr = (*head).next;
//Delete the memory address for head
delete head;
//Reassign to head the memory address of what was the memory
address of the second item
head = temp_ptr;
return;
}
IntList.h
#ifndef _INTLIST_H
#define _INTLIST_H
struct IntNode {
int data;
IntNode* next;
IntNode(int data) : data(data), next(NULL) {}
};
class IntList {
public:
IntList();
~IntList();
void display() const;
void push_front(int);
void pop_front();
bool empty() const;
private:
IntNode* head;
IntNode* tail;
};
#endif