I have pretty much failed my class (4 weeks behind in an 8 week class that is currenlty at the beginning of week 8), but I am wanting to learn C++ for myself anyhow. I have visited http://www.cplusplus.com/doc/tutorial/ and gone through the tutorial, but cannot understand this assignment. I have a working address book that was created using an array (SEVERAL .h and .cpp files are used). The first part of the assignment is to edit the files to use a linked list instead of an array. After editing to use a linked list, I need to add funtions to add or delete a new entry and write the data to the HD upon termination.
My issue is that I do not understand how to edit the original file properly. I have changed the class in addressBook.h from:
class addressBookType: public arrayListType<extPersonType>
to:
class addressBookType: public linkedListType<extPersonType>
and removed the original header files which called on a header file called arrayListType, while adding the linkedList.h and unsortedLinkedList.h headers.
What I don't understand is why I am getting an error stating that "ItelliSense: object of abstract class type "addressBookType" is not allowed:"
I do not understand why I am not allowed to call addressBookType as an abstract class. about 95% of my remaining errors have to do with the fact that addressBook is not a class due to the abstract class type not being able to be called.
I will post the main.cpp, linkedList.h, unorderedLinkedList.h, addressBookType.h and addressBookTypeImp.cpp here, but will zip the remaining files (including the old arrayType.h file) and attach them to this posting. There is a LOT of code here, but I am hoping that someone may be able to help me with understanding what I am doing wrong in trying to call the abstract class addressBookType.
main.cpp
#include <iostream>
#include <fstream>
#include <string>
#include "addressBookType.h"
using namespace std;
void loadAddressBook(addressBookType& adBook);
void saveData(addressBookType& adBook);
void showMenu();
int main()
{
addressBookType addressBook;
string str;
string str1;
string str2;
int choice;
int loc;
int month;
loadAddressBook(addressBook);
showMenu();
cin >> choice;
while (choice != 9)
{
switch (choice)
{
case 1:
cout << "Enter the last name of the person: ";
cin >> str;
cout << endl;
loc = addressBook.search(str);
if (loc != -1)
cout << str << " is in the address book" << endl;
else
cout << str << " is not in the address book" << endl;
break;
case 2:
cout << "Enter the last name of the person: ";
cin >> str;
cout << endl;
loc = addressBook.search(str);
if (loc != -1)
addressBook.printAt(loc);
else
cout << str << " is not in the address book" << endl;
break;
case 3:
cout << "Enter the month number: ";
cin >> month;
cout << endl;
addressBook.printNameInTheMonth(month);
break;
case 4:
cout << "Enter starting last name: ";
cin >> str1;
cout << endl;
cout << "Enter ending last name: ";
cin >> str2;
cout << endl;
addressBook.printNamesBetweenLastNames(str1, str2);
break;
case 5:
cout << "Enter person type Family, Friend, Business: ";
cin >> str;
cout << endl;
addressBook.printNamesWithStatus(str);
break;
case 6:
addressBook.print();
break;
case 7:
saveData(addressBook);
break;
default:
cout << "Invalid choice" << endl;
}
showMenu();
cin >> choice;
}
char response;
cout << "Save data Yes (Y/y) No(N/n)?: ";
cin >> response;
cout << endl;
if (response == 'y' || response == 'Y')
saveData(addressBook);
return 0;
}
void loadAddressBook(addressBookType& adBook)
{
ifstream infile;
char filename[50];
string first;
string last;
int month;
int day;
int year;
string street;
string city;
string state;
string zip;
string phone;
string pStatus;
extPersonType temp;
cout << "Enter file name: ";
cin >> filename;
cout << endl;
infile.open(filename);
if (!infile)
{
cout << "Input file does not exists. "
<< "Program terminates!!!" << endl;
return;
}
int i = 0;
infile >> first >> last >> month >> day >> year;
infile.ignore(100,'\n');
getline(infile,street);
getline(infile,city);
getline(infile, state);
infile >> zip >> phone >> pStatus;
while (infile)
{
temp.setInfo(first,last,month,day,year,street,city,state,
zip,phone,pStatus);
adBook.insertAt(i, temp);
i++;
infile >> first >> last >> month >> day >> year;
infile.ignore(100,'\n');
getline(infile,street);
getline(infile,city);
getline(infile, state);
infile >> zip >> phone >> pStatus;
}
}
void saveData(addressBookType& adBook)
{
ofstream outfile;
char filename[50];
cout << "Enter file name: ";
cin >> filename;
cout << endl;
outfile.open(filename);
if (!outfile)
{
cout << "Input file does not exists. "
<< "Program terminates!!!" << endl;
return;
}
adBook.saveData(outfile);
}
void showMenu()
{
cout << "Welcome to the address book program.";
cout << "Choose among the following options:" << endl;
cout << "1: To see if a person is in the address book" << endl;
cout << "2: Print the information of a person" << endl;
cout << "3: Print the names of person having birthday in a particular month" << endl;
cout << "4: Print the names of persons between two last names" << endl;
cout << "5: Print the names of persons having a particular status" << endl;
cout << "6: Print the address book" << endl;
cout << "7: Save data" << endl;
cout << "9: Terminate the program" << endl;
}
linkedList.h
#ifndef H_LinkedListType
#define H_LinkedListType
#include <iostream>
#include <cassert>
using namespace std;
//Definition of the node
template <class Type>
struct nodeType
{
Type info;
nodeType<Type> *link;
};
//***********************************************************
// Author: D.S. Malik
//
// This class specifies the members to implement an iterator
// to a linked list.
//***********************************************************
template <class Type>
class linkedListIterator
{
public:
linkedListIterator();
//Default constructor
//Postcondition: current = NULL;
linkedListIterator(nodeType<Type> *ptr);
//Constructor with a parameter.
//Postcondition: current = ptr;
Type operator*();
//Function to overload the dereferencing operator *.
//Postcondition: Returns the info contained in the node.
linkedListIterator<Type> operator++();
//Overload the preincrement operator.
//Postcondition: The iterator is advanced to the next node.
bool operator==(const linkedListIterator<Type>& right) const;
//Overload the equality operator.
//Postcondition: Returns true if this iterator is equal to
// the iterator specified by right, otherwise it returns
// false.
bool operator!=(const linkedListIterator<Type>& right) const;
//Overload the not equal to operator.
//Postcondition: Returns true if this iterator is not equal to
// the iterator specified by right, otherwise it returns
// false.
private:
nodeType<Type> *current; //pointer to point to the current
//node in the linked list
};
template <class Type>
linkedListIterator<Type>::linkedListIterator()
{
current = NULL;
}
template <class Type>
linkedListIterator<Type>::
linkedListIterator(nodeType<Type> *ptr)
{
current = ptr;
}
template <class Type>
Type linkedListIterator<Type>::operator*()
{
return current->info;
}
template <class Type>
linkedListIterator<Type> linkedListIterator<Type>::operator++()
{
current = current->link;
return *this;
}
template <class Type>
bool linkedListIterator<Type>::operator==
(const linkedListIterator<Type>& right) const
{
return (current == right.current);
}
template <class Type>
bool linkedListIterator<Type>::operator!=
(const linkedListIterator<Type>& right) const
{ return (current != right.current);
}
//***********************************************************
// Author: D.S. Malik
//
// This class specifies the members to implement the basic
// properties of a linked list. This is an abstract class.
// We cannot instantiate an object of this class.
//***********************************************************
template <class Type>
class linkedListType
{
public:
const linkedListType<Type>& operator=
(const linkedListType<Type>&);
//Overload the assignment operator.
void initializeList();
//Initialize the list to an empty state.
//Postcondition: first = NULL, last = NULL, count = 0;
bool isEmptyList() const;
//Function to determine whether the list is empty.
//Postcondition: Returns true if the list is empty, otherwise
// it returns false.
void print() const;
//Function to output the data contained in each node.
//Postcondition: none
int length() const;
//Function to return the number of nodes in the list.
//Postcondition: The value of count is returned.
void destroyList();
//Function to delete all the nodes from the list.
//Postcondition: first = NULL, last = NULL, count = 0;
Type front() const;
//Function to return the first element of the list.
//Precondition: The list must exist and must not be empty.
//Postcondition: If the list is empty, the program terminates;
// otherwise, the first element of the list is returned.
Type back() const;
//Function to return the last element of the list.
//Precondition: The list must exist and must not be empty.
//Postcondition: If the list is empty, the program
// terminates; otherwise, the last
// element of the list is returned.
virtual bool search(const Type& searchItem) const = 0;
//Function to determine whether searchItem is in the list.
//Postcondition: Returns true if searchItem is in the list,
// otherwise the value false is returned.
virtual void insertFirst(const Type& newItem) = 0;
//Function to insert newItem at the beginning of the list.
//Postcondition: first points to the new list, newItem is
// inserted at the beginning of the list, last points to
// the last node in the list, and count is incremented by
// 1.
virtual void insertLast(const Type& newItem) = 0;
//Function to insert newItem at the end of the list.
//Postcondition: first points to the new list, newItem is
// inserted at the end of the list, last points to the
// last node in the list, and count is incremented by 1.
virtual void deleteNode(const Type& deleteItem) = 0;
//Function to delete deleteItem from the list.
//Postcondition: If found, the node containing deleteItem is
// deleted from the list. first points to the first node,
// last points to the last node of the updated list, and
// count is decremented by 1.
linkedListIterator<Type> begin();
//Function to return an iterator at the beginning of the
//linked list.
//Postcondition: Returns an iterator such that current is set
// to first.
linkedListIterator<Type> end();
//Function to return an iterator one element past the
//last element of the linked list.
//Postcondition: Returns an iterator such that current is set
// to NULL.
linkedListType();
//default constructor
//Initializes the list to an empty state.
//Postcondition: first = NULL, last = NULL, count = 0;
linkedListType(const linkedListType<Type>& otherList);
//copy constructor
~linkedListType();
//destructor
//Deletes all the nodes from the list.
//Postcondition: The list object is destroyed.
protected:
int count; //variable to store the number of list elements
//
nodeType<Type> *first; //pointer to the first node of the list
nodeType<Type> *last; //pointer to the last node of the list
private:
void copyList(const linkedListType<Type>& otherList);
//Function to make a copy of otherList.
//Postcondition: A copy of otherList is created and assigned
// to this list.
};
template <class Type>
bool linkedListType<Type>::isEmptyList() const
{
return (first == NULL);
}
template <class Type>
linkedListType<Type>::linkedListType() //default constructor
{
first = NULL;
last = NULL;
count = 0;
}
template <class Type>
void linkedListType<Type>::destroyList()
{
nodeType<Type> *temp; //pointer to deallocate the memory
//occupied by the node
while (first != NULL) //while there are nodes in the list
{
temp = first; //set temp to the current node
first = first->link; //advance first to the next node
delete temp; //deallocate the memory occupied by temp
}
last = NULL; //initialize last to NULL; first has already
//been set to NULL by the while loop
count = 0;
}
template <class Type>
void linkedListType<Type>::initializeList()
{
destroyList(); //if the list has any nodes, delete them
}
template <class Type>
void linkedListType<Type>::print() const
{
nodeType<Type> *current; //pointer to traverse the list
current = first; //set current so that it points to
//the first node
while (current != NULL) //while more data to print
{
cout << current->info << " ";
current = current->link;
}
}//end print
template <class Type>
int linkedListType<Type>::length() const
{
return count;
} //end length
template <class Type>
Type linkedListType<Type>::front() const
{
assert(first != NULL);
return first->info; //return the info of the first node
}//end front
template <class Type>
Type linkedListType<Type>::back() const
{
assert(last != NULL);
return last->info; //return the info of the last node
}//end back
template <class Type>
linkedListIterator<Type> linkedListType<Type>::begin()
{
linkedListIterator<Type> temp(first);
return temp;
}
template <class Type>
linkedListIterator<Type> linkedListType<Type>::end()
{
linkedListIterator<Type> temp(NULL);
return temp;
}
template <class Type>
void linkedListType<Type>::copyList
(const linkedListType<Type>& otherList)
{
nodeType<Type> *newNode; //pointer to create a node
nodeType<Type> *current; //pointer to traverse the list
if (first != NULL) //if the list is nonempty, make it empty
destroyList();
if (otherList.first == NULL) //otherList is empty
{
first = NULL;
last = NULL;
count = 0;
}
else
{
current = otherList.first; //current points to the
//list to be copied
count = otherList.count;
//copy the first node
first = new nodeType<Type>; //create the node
first->info = current->info; //copy the info
first->link = NULL; //set the link field of
//the node to NULL
last = first; //make last point to the
//first node
current = current->link; //make current point to
//the next node
//copy the remaining list
while (current != NULL)
{
newNode = new nodeType<Type>; //create a node
newNode->info = current->info; //copy the info
newNode->link = NULL; //set the link of
//newNode to NULL
last->link = newNode; //attach newNode after last
last = newNode; //make last point to
//the actual last node
current = current->link; //make current point
//to the next node
}//end while
}//end else
}//end copyList
template <class Type>
linkedListType<Type>::~linkedListType() //destructor
{
destroyList();
}//end destructor
template <class Type>
linkedListType<Type>::linkedListType
(const linkedListType<Type>& otherList)
{
first = NULL;
copyList(otherList);
}//end copy constructor
//overload the assignment operator
template <class Type>
const linkedListType<Type>& linkedListType<Type>::operator=
(const linkedListType<Type>& otherList)
{
if (this != &otherList) //avoid self-copy
{
copyList(otherList);
}//end else
return *this;
}
#endif
unorderedLinkedList.h
#ifndef H_UnorderedLinkedList
#define H_UnorderedLinkedList
//***********************************************************
// Author: D.S. Malik
//
// This class specifies the members to implement the basic
// properties of an unordered linked list. This class is
// derived from the class linkedListType.
//***********************************************************
#include "linkedList.h"
using namespace std;
template <class Type>
class unorderedLinkedList: public linkedListType<Type>
{
public:
bool search(const Type& searchItem) const;
//Function to determine whether searchItem is in the list.
//Postcondition: Returns true if searchItem is in the list,
// otherwise the value false is returned.
void insertFirst(const Type& newItem);
//Function to insert newItem at the beginning of the list.
//Postcondition: first points to the new list, newItem is
// inserted at the beginning of the list, last points to
// the last node, and count is incremented by 1.
//
void insertLast(const Type& newItem);
//Function to insert newItem at the end of the list.
//Postcondition: first points to the new list, newItem is
// inserted at the end of the list, last points to the
// last node, and count is incremented by 1.
void deleteNode(const Type& deleteItem);
//Function to delete deleteItem from the list.
//Postcondition: If found, the node containing deleteItem
// is deleted from the list. first points to the first
// node, last points to the last node of the updated
// list, and count is decremented by 1.
};
template <class Type>
bool unorderedLinkedList<Type>::
search(const Type& searchItem) const
{
nodeType<Type> *current; //pointer to traverse the list
bool found = false;
current = first; //set current to point to the first
//node in the list
while (current != NULL && !found) //search the list
if (current->info == searchItem) //searchItem is found
found = true;
else
current = current->link; //make current point to
//the next node
return found;
}//end search
template <class Type>
void unorderedLinkedList<Type>::insertFirst(const Type& newItem)
{
nodeType<Type> *newNode; //pointer to create the new node
newNode = new nodeType<Type>; //create the new node
newNode->info = newItem; //store the new item in the node
newNode->link = first; //insert newNode before first
first = newNode; //make first point to the
//actual first node
count++; //increment count
if (last == NULL) //if the list was empty, newNode is also
//the last node in the list
last = newNode;
}//end insertFirst
template <class Type>
void unorderedLinkedList<Type>::insertLast(const Type& newItem)
{
nodeType<Type> *newNode; //pointer to create the new node
newNode = new nodeType<Type>; //create the new node
newNode->info = newItem; //store the new item in the node
newNode->link = NULL; //set the link field of newNode
//to NULL
if (first == NULL) //if the list is empty, newNode is
//both the first and last node
{
first = newNode;
last = newNode;
count++; //increment count
}
else //the list is not empty, insert newNode after last
{
last->link = newNode; //insert newNode after last
last = newNode; //make last point to the actual
//last node in the list
count++; //increment count
}
}//end insertLast
template <class Type>
void unorderedLinkedList<Type>::deleteNode(const Type& deleteItem)
{
nodeType<Type> *current; //pointer to traverse the list
nodeType<Type> *trailCurrent; //pointer just before current
bool found;
if (first == NULL) //Case 1; the list is empty.
cout << "Cannot delete from an empty list."
<< endl;
else
{
if (first->info == deleteItem) //Case 2
{
current = first;
first = first->link;
count--;
if (first == NULL) //the list has only one node
last = NULL;
delete current;
}
else //search the list for the node with the given info
{
found = false;
trailCurrent = first; //set trailCurrent to point
//to the first node
current = first->link; //set current to point to
//the second node
while (current != NULL && !found)
{
if (current->info != deleteItem)
{
trailCurrent = current;
current = current-> link;
}
else
found = true;
}//end while
if (found) //Case 3; if found, delete the node
{
trailCurrent->link = current->link;
count--;
if (last == current) //node to be deleted
//was the last node
last = trailCurrent; //update the value
//of last
delete current; //delete the node from the list
}
else
cout << "The item to be deleted is not in "
<< "the list." << endl;
}//end else
}//end else
}//end deleteNode
#endif
addressBookType.h
//addressBookType.h
#ifndef H_addressBookType
#define H_addressBookType
#include <string>
#include <fstream>
#include "extPersonType.h"
#include "unorderedLinkedList.h"
using namespace std;
class addressBookType: public linkedListType<extPersonType>
{
public:
void print() const;
void printNameInTheMonth(int month);
void printInfoOf(string lName);
void printNamesWithStatus(string status);
void printAt(int i);
void printNamesBetweenLastNames(string last1, string last2);
int search(string lName);
void saveData(ofstream&);
addressBookType();
};
#endif
addressBookTypeImp.cpp
//addressBookTypeImp.cpp
#include <iostream>
#include <fstream>
#include <string>
#include "addressBookType.h"
using namespace std;
void addressBookType::print() const
{
adBook.print();
}
void addressBookType::printNameInTheMonth(int month)
{
if (linkedListType.search() == true)
{
linkedListType.print();
}
}
void addressBookType::printInfoOf(string lName)
{
int i = search(lName);
if (i != -1)
addressBook.printInfo();
else
cout << lName << " is not in address book." << endl;
}
void addressBookType::printNamesWithStatus(string status)
{
for (int i = 0; i < length(); i++)
if (list[i].isStatus(status))
{
list[i].print();
cout << endl;
}
}
void addressBookType::printAt(int i)
{
if (i < length())
list[i].printInfo();
else
cout << "No such person" << endl;
}
void addressBookType::printNamesBetweenLastNames(string last1, string last2)
{
string lName;
for (int i = 0; i < length(); i++)
{
list[i].getLastName(lName);
if (last1 <= lName && lName <= last2)
{
list[i].print();
cout << endl;
}
}
}
int addressBookType::search(string lName)
{
bool found = false;
int i = 0;
for (i = 0; i < length(); i++)
if (list[i].isLastName(lName))
{
found = true;
break;
}
if (found)
return i;
else
return -1;
}
/*addressBookType::addressBookType()
{
length = 0;
}*/
void addressBookType::saveData(ofstream& outFile)
{
string first;
string last;
int month;
int day;
int year;
string street;
string city;
string state;
string zip;
string phone;
string pStatus;
for (int i = 0; i < length(); i++)
{
list[i].getName(first,last);
list[i].getDOB(month, day, year);
list[i].getAddress(street,city,state,zip);
list[i].getPhoneNumber(phone);
list[i].getStatus(pStatus);
outFile << first << " " << last << endl;
outFile << month << " " << day << " " << year << endl;
outFile << street << endl << city << endl << state << endl << zip << endl;
outFile << phone << endl << pStatus << endl;
}
}
Please Note that the arrayType.h file is the OLD file. I included it for reference purposes as if it is included and line 13 is edited in addressBookType.h then the program runs correctly.
Thank you for any advice / guidence you can give me in understanding how to call linked lists.