vendredi 1 mai 2020

Out of Scope Error using private Inheritance

I'm working on stacks in C++ and I've created my own stack class that inherits privately from a linked list class I created. However, when I call a function of the stack class, I get an error saying that function was not declared in the scope. Here is the error message:

Stack.h|15|error: 'insertAtFront' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]|

Also, the implementation of my stack class is basically just using some member functions of my linked list class to implement push() and pop() functionality of my stack. Here is my stack header file:

#define STACK_H

#include "List.h" // List class definition

template< typename STACKTYPE >
class Stack : private List< STACKTYPE > 
{
public:
   // push calls the List function insertAtFront
   void push( const STACKTYPE &data ) 
   { 
      insertAtFront( data ); 
   } // end function push

   // pop calls the List function removeFromFront
   bool pop( STACKTYPE &data ) 
   { 
      return removeFromFront( data ); 
   } // end function pop

   // isStackEmpty calls the List function isEmpty
   bool isStackEmpty() const 
   { 
      return this->isEmpty();
   } // end function isStackEmpty

   // printStack calls the List function print
   void printStack() const 
   { 
      this->print();
   } // end function print 
}; // end class Stack

#endif

Here is my Linked List header file also

#ifndef LIST_H
#define LIST_H

#include <iostream>
#include "ListNode.h" // ListNode class definition
using namespace std;

template< typename NODETYPE >
class List
{
public:
   List(); // constructor
   ~List(); // destructor
   ListNode<NODETYPE> * getFirstPointer() const;
   List<NODETYPE> concatList(List<NODETYPE> &) const;
    List<NODETYPE> reverseList() const;
   int getSize();
   void BubbleSort(ListNode <NODETYPE> *) const;
   double sum();
   void insertAtFront( const NODETYPE & );
   void insertAtBack( const NODETYPE & );
   bool removeFromFront( NODETYPE & );
   bool removeFromBack( NODETYPE & );
   bool isEmpty() const;
   void print() const;
private:
   ListNode< NODETYPE > *firstPtr; // pointer to first node
   ListNode< NODETYPE > *lastPtr; // pointer to last node
   int list_size = 0; //size of linked list

   // utility function to allocate new node
   ListNode< NODETYPE > *getNewNode( const NODETYPE & );
}; // end class List

// default constructor
template< typename NODETYPE >
List< NODETYPE >::List()
   : firstPtr( 0 ), lastPtr( 0 )
{
   // empty body
} // end List constructor

// destructor
template< typename NODETYPE >
List< NODETYPE >::~List()
{
   if ( !isEmpty() ) // List is not empty
   {
      cout << "Destroying nodes ...\n";

      ListNode< NODETYPE > *currentPtr = firstPtr;
      ListNode< NODETYPE > *tempPtr;

      while ( currentPtr != 0 ) // delete remaining nodes
      {
         tempPtr = currentPtr;
         cout << tempPtr->data << '\n';
         currentPtr = currentPtr->nextPtr;
         delete tempPtr;
      } // end while
   } // end if

   cout << "All nodes destroyed\n\n";
} // end List destructor

template< typename NODETYPE >
ListNode< NODETYPE > * List<NODETYPE>::getFirstPointer() const{
    return firstPtr;
}

template< typename NODETYPE >
List< NODETYPE > List<NODETYPE>::concatList(List<NODETYPE> &listobj) const{
    if(listobj.isEmpty()){
        cout<<"Empty List, concat failed"<<endl;
        return *this;
    }
    else {
        ListNode<NODETYPE> *ptr = getFirstPointer();
        NODETYPE data;
        while (ptr != 0){
            data = ptr->data;
            listobj.insertAtBack(data);
            ptr = ptr->nextPtr;
        }

        return listobj;
    }
}

template < typename NODETYPE >
int List< NODETYPE >::getSize() {
    return list_size;
}

template < typename NODETYPE >
List< NODETYPE > List< NODETYPE >::reverseList() const{
    List< NODETYPE > listobj;
    if(this->isEmpty()){
        cout<<"Empty List, reverse failed"<<endl;
        return *this;
    }
    else {
        ListNode<NODETYPE> *ptr = firstPtr;
        NODETYPE data;
        while (ptr != 0){
            data = ptr->data;
            listobj.insertAtFront(data);
            ptr = ptr->nextPtr;
        }

        return listobj;
    }
}

template <typename NODETYPE>
void List< NODETYPE >::BubbleSort(ListNode< NODETYPE > *ptr) const{
    int swapped;
    NODETYPE temp;
    ListNode <NODETYPE> *ptr1;
    ListNode <NODETYPE> *ptr2 = 0;

    if (ptr == 0)
        return;
    do{
        swapped = 0;
        ptr1 = ptr; // assign initial pointer
        while(ptr1->nextPtr != ptr2){
            if(ptr1->data > ptr1->nextPtr->data){
                temp = ptr1->data;
                ptr1->data = ptr1->nextPtr->data;
                ptr1->nextPtr->data = temp;
                swapped = 1;
        } //end if
        ptr1 = ptr1->nextPtr;
    }//end while
        ptr2 = ptr1;
    }//end do
    while(swapped);
}

template <typename NODETYPE>
double List< NODETYPE >::sum(){
    double sum = 0;
    if(this->isEmpty()){
        cout<<"Empty List, sum is 0"<<endl;
        return 0;
    }
    else {
        ListNode<NODETYPE> *ptr = firstPtr;
        NODETYPE data;
        while (ptr != 0){
            data = ptr->data;
            sum += data;
            ptr = ptr->nextPtr;
        }//end while
    } //end else
     return sum;
}

// insert node at front of list
template< typename NODETYPE >
void List< NODETYPE >::insertAtFront( const NODETYPE &value )
{
   ListNode< NODETYPE > *newPtr = getNewNode( value ); // new node

   if ( isEmpty() ) // List is empty
      firstPtr = lastPtr = newPtr; // new list has only one node
   else // List is not empty
   {
      newPtr->nextPtr = firstPtr; // point new node to previous 1st node
      firstPtr = newPtr; // aim firstPtr at new node
   } // end else
   list_size += 1;
} // end function insertAtFront

// insert node at back of list
template< typename NODETYPE >
void List< NODETYPE >::insertAtBack( const NODETYPE &value )
{
   ListNode< NODETYPE > *newPtr = getNewNode( value ); // new node

   if ( isEmpty() ) // List is empty
      firstPtr = lastPtr = newPtr; // new list has only one node
   else // List is not empty
   {
      lastPtr->nextPtr = newPtr; // update previous last node
      lastPtr = newPtr; // new last node
   } // end else
   list_size += 1;
} // end function insertAtBack

// delete node from front of list
template< typename NODETYPE >
bool List< NODETYPE >::removeFromFront( NODETYPE &value )
{
   if ( isEmpty() ) // List is empty
      return false; // delete unsuccessful
   else
   {
      ListNode< NODETYPE > *tempPtr = firstPtr; // hold tempPtr to delete

      if ( firstPtr == lastPtr )
         firstPtr = lastPtr = 0; // no nodes remain after removal
      else
         firstPtr = firstPtr->nextPtr; // point to previous 2nd node

      value = tempPtr->data; // return data being removed
      delete tempPtr; // reclaim previous front node
      list_size = list_size - 1;
      return true; // delete successful
   } // end else
} // end function removeFromFront

// delete node from back of list
template< typename NODETYPE >
bool List< NODETYPE >::removeFromBack( NODETYPE &value )
{
   if ( isEmpty() ) // List is empty
      return false; // delete unsuccessful
   else
   {
      ListNode< NODETYPE > *tempPtr = lastPtr; // hold tempPtr to delete

      if ( firstPtr == lastPtr ) // List has one element
         firstPtr = lastPtr = 0; // no nodes remain after removal
      else
      {
         ListNode< NODETYPE > *currentPtr = firstPtr;

         // locate second-to-last element
         while ( currentPtr->nextPtr != lastPtr )
            currentPtr = currentPtr->nextPtr; // move to next node

         lastPtr = currentPtr; // remove last node
         currentPtr->nextPtr = 0; // this is now the last node
      } // end else

      value = tempPtr->data; // return value from old last node
      delete tempPtr; // reclaim former last node
      list_size = list_size - 1;
      return true; // delete successful
   } // end else
} // end function removeFromBack

// is List empty?
template< typename NODETYPE >
bool List< NODETYPE >::isEmpty() const
{
   return firstPtr == 0;
} // end function isEmpty

// return pointer to newly allocated node
template< typename NODETYPE >
ListNode< NODETYPE > *List< NODETYPE >::getNewNode(
   const NODETYPE &value )
{
   return new ListNode< NODETYPE >( value );
} // end function getNewNode

// display contents of List
template< typename NODETYPE >
void List< NODETYPE >::print() const
{
   if ( isEmpty() ) // List is empty
   {
      cout << "The list is empty\n\n";
      return;
   } // end if

   ListNode< NODETYPE > *currentPtr = firstPtr;

   cout << "The list is: ";

   while ( currentPtr != 0 ) // get element data
   {
      cout << currentPtr->data << ' ';
      currentPtr = currentPtr->nextPtr;
   } // end while

   cout << "\n\n";
} // end function print

#endif

And here is my implementation file

int main()
{
   Stack< int > intStack; // create Stack of ints

   cout << "processing an integer Stack" << endl;

   // push integers onto intStack
   for ( int i = 0; i < 3; i++ ) 
   {
      intStack.push( i );
      intStack.printStack();
   } // end for
   }

I've also run the example code in the textbook where I'm learning from and I get the same error. Any help with regards to why this program does not compile would be of great help to me. Thanks.

Aucun commentaire:

Enregistrer un commentaire