First off before anyone ask... yes this is homework. I have managed to get the basic of the program to compile and run correctly and now I'm working on the last piece which is a sorted insert. However, I receive the following error and I'm not sure why between lines 82-94 of the ABook.cpp file when trying to compile (it is commented in the code below)...'class AddressNode<std::string>' has no member named 'next'
If anyone could explain why this code doesn't work here but does everywhere else it be greatly appreciated that way I have some sort of direction as to where to look to fix it.
Background: The assignment is to create a structure called AddressNode and a class called ABook this class is a linked list that can insert items in a sorted order...
#ifndef ABook_H
#define ABook_H
#include <iostream>
#include <new>
#include<string>
#include "AddressNode.h"
usingnamespace std;
template< typename NODETYPE >
class ABook
{
public:
ABook(); // default constructor
~ABook(); // destructor
void Insert( const NODETYPE & );//inserts at beginning of list
void SortedInsert( const NODETYPE & );//inserts in correct order
bool Remove( NODETYPE & );//pops value from front of list and prints it to the screen
bool empty() const;//checks to see if a list contains any nodes
void print() const;//prints list
private:
AddressNode< NODETYPE > *topPtr; // pointer to first node
AddressNode< NODETYPE > *lastPtr; // pointer to last node
AddressNode< NODETYPE > *getNewNode( const NODETYPE & );// create new node
}; // end class template ABook
// default constructor
template< typename NODETYPE >
ABook< NODETYPE >::ABook()
{
topPtr = lastPtr = 0;
} // end constructor
// destructor
template< typename NODETYPE >
ABook< NODETYPE >::~ABook()
{
if (!empty()){ // ABook is not empty
AddressNode< NODETYPE > *currentPtr = topPtr;
AddressNode< NODETYPE > *tempPtr;
while ( currentPtr != 0 ){ // delete remaining nodes
tempPtr = currentPtr;
cout << "Destroying: " << tempPtr->data << '\n';
currentPtr = currentPtr->nextPtr;
delete tempPtr;
}
}
cout << "\nDestructor Successful: All nodes destroyed\n\n";
system("pause");//shows that destructor was successful
} // end destructor
// Insert a node at the front of the list
template< typename NODETYPE >
void ABook< NODETYPE >::Insert( const NODETYPE &value )
{
AddressNode<NODETYPE> *newPtr = getNewNode( value );
if ( empty() ) // checks to see if the list is empty then inserts at front
topPtr = lastPtr = newPtr;
else{ // if its not empty, assign the pointers to the correct nodes
newPtr->nextPtr = topPtr;
topPtr = newPtr;
} // end else
} // end function insertAtFront
//Insert a node in order
template< typename NODETYPE >
void ABook< NODETYPE >::SortedInsert( const NODETYPE &value )
{
AddressNode< NODETYPE > *newPtr = getNewNode(value);
if (empty())
topPtr = newPtr;// if the list is empty make it the first node
//-------------------'class AddressNode<std::string>' has no member named 'next'---------------------------------
elseif(topPtr->data > newPtr->data){//compare new value to current value
newPtr->next = topPtr;
topPtr = newPtr;
}
else{
for( AddressNode< NODETYPE > *ptr = topPtr; ptr->next != NULL; ptr = ptr->next ){
if(ptr->next > newPtr){ // Item is > than ptr
newPtr->next = ptr->next; // Insert item after ptr
ptr->next = newPtr;
break;
}
if( ptr->next == NULL ){ // Reached end without inserting
ptr->next = newPtr; // Insert at end
newPtr->next = NULL;
}
}//end for
//-------------------'class AddressNode<std::string>' has no member named 'next'---------------------------------
}//end if
}//end sortedinsert
// Delete a node from the front of the ABook
template< typename NODETYPE >
bool ABook< NODETYPE >::Remove( NODETYPE &value )
{
if ( empty() ) // ABook is empty
returnfalse; // delete unsuccessful
else
{
AddressNode< NODETYPE > *tempPtr = topPtr;
if ( topPtr == lastPtr )
topPtr = lastPtr = 0;
else
topPtr = topPtr->nextPtr;
value = tempPtr->data; // data being removed
delete tempPtr;
returntrue; // delete successful
} // end else
} // end function removeFromFront
// Is the ABook empty?
template< typename NODETYPE >
bool ABook< NODETYPE >::empty() const
{
return topPtr == 0;
} // end function isEmpty
// assigns pointer to a new node
template< typename NODETYPE >
AddressNode< NODETYPE > *ABook< NODETYPE >::getNewNode(const NODETYPE &value)
{
AddressNode< NODETYPE > *ptr = new AddressNode< NODETYPE >( value );
return ptr;
} // end function getNewNode
template< typename NODETYPE >
void ABook< NODETYPE >::print() const
{//Prints linked list
if ( empty() ){ // empty ABook
cout << "The ABook is empty\n\n";
return;
}
AddressNode< NODETYPE > *currentPtr = topPtr;
cout << "The ABook is:\n";
while ( currentPtr != 0 ){ // display elements in ABook
cout << currentPtr->data << '\n';
currentPtr = currentPtr->nextPtr;
}
cout << "\n\n";
} // end function print
#endif
//----------------------------Week5-6Program.cpp-------------------------------
int main()
{
ABook< string > Book; // storage for first ABook
string newName[4] = {"Precious","Ken","Eileen","Frank"};
string nameToRemove[4] = {"Precious","Ken","Eileen","Frank"};
int i = 0;
for ( i; i < 1; i++ )
Book.Insert(newName[i]);
for(i; i < 4; i++)
Book.SortedInsert(newName[i]);
Book.print();
system("pause");
return 0; // indicates successful termination
} // end main
You get 'class AddressNode<std::string>' has no member named 'next' because it has no member named 'next'. Just look at it. It has a private member AddressNode (It's not good to name your variables the same way as your classes. It is weird that there is no error/warning about it..) and a function getNextPtr.
Ya, I figured out the problem about 2 seconds after I hit post... 'next' is not the proper name for the member.... it would be 'nextPtr'... so once I figured out that dumb mistake I've ran into one last problem that I can't seem to figure out.
When I attempt to insert a node in the middle, I fail miserably. Though I think I know what the problem is... I create the node and point it to the one that its pushing to the right of the list... but where I fail is that I don't tell the node before it where to find the new node... it still points to the one I just pushed to the right. So when I go to print... it simple skips my new node. For instance, I have 3 nodes (1,2,3)... I insert a new 4 node between 1 and 2 (1,4,2,3)... even though 4 is pointing to 2 correctly, 1 is still pointing at 2 instead of pointing to 4. What is the best approach to fixing this? I thought about making a temp node that stores the pointer each loop... but it still wouldn't allow me to assign a new value to a pointer that has already been passed by... the code below is where the problem lies as well as the rest of the program...
The problem child:
1 2 3 4 5 6 7 8 9 10 11
//------------------------------------------------------------------------------------------------------------------
if(newPtr->data < currPtr->data){ // If new item is less than the next in list insert and shift every right
/*****************************************************************************
* should look like this.... how do you assign the previous pointer????
* newPtr->nextPtr = currPtr;//point new node to current node that is being shifted one right
* prevPtr->nextPtr = newPtr;//point previous node to new node
****************************************************************************/
newPtr->nextPtr = currPtr;//point new node to current node that is being shifted one right
newPtr->nextPtr->data = currPtr->data;
break;
}//end if
#ifndef ABook_H
#define ABook_H
#include <iostream>
#include <new>
#include<string>
#include "list_node.h"
usingnamespace std;
template< typename NODETYPE >
class ABook
{
public:
ABook(); // default constructor
~ABook(); // destructor
void Insert( const NODETYPE & );//inserts at beginning of list
void SortedInsert( const NODETYPE & );//inserts in Acending order
bool Remove( NODETYPE & );//pops value from front of list and prints it to the screen
bool empty() const;//checks to see if a list contains any nodes
void print() const;//prints list
private:
AddressNode< NODETYPE > *topPtr; // pointer to first node
AddressNode< NODETYPE > *lastPtr; // pointer to last node
AddressNode< NODETYPE > *getNewNode( const NODETYPE & );// create new node
}; // end class template ABook
// default constructor
template< typename NODETYPE >
ABook< NODETYPE >::ABook()
{
topPtr = lastPtr = NULL;
} // end constructor
// destructor
template< typename NODETYPE >
ABook< NODETYPE >::~ABook()
{
if (!empty()){ // ABook is not empty
AddressNode< NODETYPE > *currentPtr = topPtr;
AddressNode< NODETYPE > *tempPtr;
while ( currentPtr != 0 ){ // delete remaining nodes
tempPtr = currentPtr;
cout << "Destroying: " << tempPtr->data << '\n';
currentPtr = currentPtr->nextPtr;
delete tempPtr;
}
}
cout << "\nDestructor Successful: All nodes destroyed\n\n";
system("pause");//shows that destructor was successful
} // end destructor
// Insert a node at the front of the list
template< typename NODETYPE >
void ABook< NODETYPE >::Insert( const NODETYPE &value )
{
AddressNode<NODETYPE> *newPtr = getNewNode( value );
if ( empty() ){
// checks to see if the list is empty if it is, inserts at front
topPtr = lastPtr = newPtr;
}
else{
//if its not empty insert at beginning and push everything else right
newPtr->nextPtr = topPtr;
topPtr = newPtr;
} // end else
} // end function Insert
//Insert a node in order
template< typename NODETYPE >
void ABook< NODETYPE >::SortedInsert( const NODETYPE &value )
{
AddressNode< NODETYPE > *newPtr = getNewNode(value);
if (empty()){
//if there is nothing on the list yet make it the first node
lastPtr = topPtr = newPtr;
}
elseif(newPtr->data < topPtr->data){
//if new data is less than first element, insert as first element and push everything else right (assumes list is sorted)
newPtr->nextPtr = topPtr;
topPtr = newPtr;
}
else{
print();
cout << "Name being inserted: " << newPtr->data << '\n'; // diag
for( AddressNode< NODETYPE > *currPtr = topPtr; currPtr != NULL; currPtr = currPtr->nextPtr ){
//iterate through list till the proper place is found to insert the new item
//------------------------------------------------------------------------------------------------------------------
if(newPtr->data < currPtr->data){ // If new item is less than the next in list insert and shift every right
newPtr->nextPtr = currPtr;//point new node to current node that is being shifted one right
newPtr->nextPtr->data = currPtr->data;
break;
}//end if
//------------------------------------------------------------------------------------------------------------------
if( currPtr->nextPtr == NULL ){
//If it is the greatest value in the list, place it at the end
lastPtr = currPtr->nextPtr = newPtr; // Insert at end
newPtr->nextPtr = NULL;
}
}//end for
}//end if
}//end sortedinsert
// Delete a node from the front of the ABook
template< typename NODETYPE >
bool ABook< NODETYPE >::Remove( NODETYPE &value )
{
if ( empty() ) // ABook is empty
returnfalse; // delete unsuccessful
else
{
AddressNode< NODETYPE > *tempPtr = topPtr;
if ( topPtr == lastPtr )
topPtr = lastPtr = NULL;
else
topPtr = topPtr->nextPtr;
value = tempPtr->data; // data being removed
delete tempPtr;
returntrue; // delete successful
} // end else
} // end function remove
// Is the ABook empty?
template< typename NODETYPE >
bool ABook< NODETYPE >::empty() const
{
return topPtr == NULL;
} // end function isEmpty
// assigns pointer to a new node
template< typename NODETYPE >
AddressNode< NODETYPE > *ABook< NODETYPE >::getNewNode(const NODETYPE &value)
{
AddressNode< NODETYPE > *ptr = new AddressNode< NODETYPE >( value );
return ptr;
} // end function getNewNode
template< typename NODETYPE >
void ABook< NODETYPE >::print() const
{//Prints linked list
if ( empty() ){ // empty ABook
cout << "The ABook is empty\n\n";
return;
}
AddressNode< NODETYPE > *currentPtr = topPtr;
cout << "\n\nThe ABook is:\n";
while ( currentPtr != NULL ){
// cycle through nodes until the end is reached
cout << currentPtr->data << '\n';
currentPtr = currentPtr->nextPtr;
}
cout << "\n\n";
} // end function print
#endif
//----------------------------Week5-6Program.cpp-------------------------------
int main()
{
ABook< string > Book; // storage for first ABook
string newName[4] = {"Ken","Eileen","Frank","Precious"};//this does
string nameToRemove[4] = {"Precious","Ken","Eileen","Frank"};//this doesn't use 4 names
cout << "input order: \n";
for(int i = 0; i < 4; i++)
cout << newName[i] << '\n';
cout << '\n';
Book.Insert(newName[0]);
Book.SortedInsert(newName[1]);
Book.SortedInsert(newName[2]);
Book.SortedInsert(newName[3]);
Book.print();
system("pause");
return 0; // indicates successful termination
} // end main