Link to home
Start Free TrialLog in
Avatar of brich744
brich744

asked on

Error: Expression must have a class type

Hello Everyone,

I am creating a template for a stack class and an binaryNode class.  I want to create a stack that will hold pointers to the binaryNode objects.  When I try to declare my stack object I receive the error Expression must have a class type.  Here is main code.

 
int main()
{
	Stack<BinaryNode<char>*> ptrStack();
	
   char equation[20];
   char* tokenPtr;

   cout<<"Please Enter In A Equation"<<endl;

   cin.getline(equation, '\n');
   
   tokenPtr = strtok(equation," ");

   while( tokenPtr != NULL)
   {
	   cout<<tokenPtr<<endl;
	   

	   if(*tokenPtr == '(' || *tokenPtr == ')' || *tokenPtr == '+' || *tokenPtr=='-')
	   {

		   cout<<"This Is A Operator"<<endl;
		   BinaryNode<char> newNode(*tokenPtr);

		   
	   }

	   else
	   {
		   BinaryNode<char> newNode(*tokenPtr);
		   ptrStack.push(newNode);
		   
	   }
	   tokenPtr = strtok(NULL, " ");

   }


	
	system("PAUSE");

	return 0;
}

Open in new window



Here is my constructor for stack

 
template<>
Stack<BinaryNode<char>*>::Stack()
{
	topOfStack = NULL;

}

Open in new window



Here is my constructor for binaryNode

 
template <class Object>
BinaryNode<Object>::BinaryNode( const Object & theElement,
                                BinaryNode *lt, BinaryNode *rt )
  : element( theElement ), left( lt ), right( rt )
{ 
}

Open in new window

Avatar of Infinity08
Infinity08
Flag of Belgium image

What is the exact (and complete) error message that you get ? What line does it refer to ? Can you also post the class definitions for Stack and BinaryNode ?
Avatar of brich744
brich744

ASKER

Error:       1      IntelliSense: expression must have class type      c:\users\owner\documents\visual studio 2010\projects\binarytree\binarytree\main.cpp      45      6      BinaryTree

Main Class:

 
#include<iostream>
#include<string>
#include<cstring>
#include<sstream>
#include<iterator>
#include<vector>
#include<algorithm>

using namespace std;

#include"StackLi.h"
#include"BinaryTree.h"


int main()
{
	Stack<BinaryNode<char>*> ptrStack();
	
   char equation[20];
   char* tokenPtr;

   cout<<"Please Enter In A Equation"<<endl;

   cin.getline(equation, '\n');
   
   tokenPtr = strtok(equation," ");

   while( tokenPtr != NULL)
   {
	   cout<<tokenPtr<<endl;
	   

	   if(*tokenPtr == '(' || *tokenPtr == ')' || *tokenPtr == '+' || *tokenPtr=='-')
	   {

		   cout<<"This Is A Operator"<<endl;
		   BinaryNode<char> newNode(*tokenPtr);

		   
	   }

	   else
	   {
		   BinaryNode<char> newNode(*tokenPtr);
		   ptrStack.push(newNode);
		   
	   }
	   tokenPtr = strtok(NULL, " ");

   }


	
	system("PAUSE");

	return 0;
}

Open in new window


Stack Class:

 
#ifndef STACKLI_H_
#define STACKLI_H_

#include <stdlib.h>

using namespace std;

#include"BinaryTree.h"
//#include "Except.h"


// Stack class -- linked list implementation.
//
// CONSTRUCTION: with no parameters.
//
// ******************PUBLIC OPERATIONS*********************
// void push( x )        --> Insert x
// void pop( )           --> Remove most recently inserted item
// Object top( )         --> Return most recently inserted item
// Object topAndPop( )   --> Return and remove most recently inserted item
// bool isEmpty( )       --> Return true if empty; else false
// void makeEmpty( )     --> Remove all items
// ******************ERRORS********************************
// UnderflowException thrown as needed.

template <class Object>
class Stack
{
  public:
    Stack( );
    Stack( const Stack & );
	Stack();
    ~Stack( );

    bool isEmpty( ) const;
    const Object & top( ) const;

    void makeEmpty( );
    void pop( );
    void push( const Object & );
    Object topAndPop( );

    const Stack & operator=( const Stack & );

  private:
    struct ListNode
    {
        Object    element;
        ListNode *next;

        ListNode( const Object & theElement, ListNode * n = NULL )
          : element( theElement ), next( n ) { }
    };

    ListNode *topOfStack;
};

//#include "StackLi.cpp"


// Construct the stack.
template <class Object>
Stack<Object>::Stack( )
{
    topOfStack = NULL;
}

// Copy constructor.
template <class Object>
Stack<Object>::Stack( const Stack<Object> & rhs )
{
    topOfStack = NULL;
    *this = rhs;
}


template<>
Stack<BinaryNode<char>*>::Stack()
{
	topOfStack = NULL;

}

// Destructor.
template <class Object>
Stack<Object>::~Stack( )
{
    makeEmpty( );
}

// Test if the stack is logically empty.
// Return true if empty, false, otherwise.
template <class Object>
bool Stack<Object>::isEmpty( ) const
{
    return topOfStack == NULL;
}

// Make the stack logically empty.
template <class Object>
void Stack<Object>::makeEmpty( )
{
    while( !isEmpty( ) )
        pop( );
}

// Return the most recently inserted item in the stack.
// or throw an UnderflowException if empty.
template <class Object>
const Object & Stack<Object>::top( ) const
{
    if( isEmpty( ) )
        throw UnderflowException( );
    return topOfStack->element;
}

// Remove the most recently inserted item from the stack.
// Throw Underflow if the stack is empty.
template <class Object>
void Stack<Object>::pop( )
{
    if( isEmpty( ) )
        throw UnderflowException( );

    ListNode *oldTop = topOfStack;
    topOfStack = topOfStack->next;
    delete oldTop;
}

// Return and remove the most recently inserted item
// from the stack.
template <class Object>
Object Stack<Object>::topAndPop( )
{
    Object topItem = top( );
    pop( );
    return topItem;
}

// Insert x into the stack.
template <class Object>
void Stack<Object>::push( const Object & x )
{
    topOfStack = new ListNode( x, topOfStack );
}

// Deep copy.
template <class Object>
const Stack<Object> & Stack<Object>::operator=( const Stack<Object> & rhs )
{
    if( this != &rhs )
    {
        makeEmpty( );
        if( rhs.isEmpty( ) )
            return *this;

        ListNode *rptr = rhs.topOfStack;
        ListNode *ptr  = new ListNode( rptr->element );
        topOfStack = ptr;

        for( rptr = rptr->next; rptr != NULL; rptr = rptr->next )
            ptr = ptr->next = new ListNode( rptr->element );
    }
    return *this;
}



#endif

Open in new window


BinaryNode Class:

 
#ifndef BINARYTREE_H_
#define BINARYTREE_H_

#include <stdlib.h>

template <class Object>
class BinaryTree;

// BinaryNode class; stores a node in a tree.
//
// CONSTRUCTION: with (a) no parameters, or (b) an Object,
//     or (c) an Object, left pointer, and right pointer.
//
// *******************PUBLIC OPERATIONS**********************
// int size( )            --> Return size of subtree at node
// int height( )          --> Return height of subtree at node
// void printPostOrder( ) --> Print a postorder tree traversal
// void printInOrder( )   --> Print an inorder tree traversal
// void printPreOrder( )  --> Print a preorder tree traversal
// BinaryNode * duplicate( )    --> Return a duplicate tree
// *******************ERRORS*********************************
// None.

template <class Object>
class BinaryNode
{
  public:
    BinaryNode( const Object & theElement = Object( ),
                BinaryNode *lt = NULL, BinaryNode *rt = NULL );

    static int size( BinaryNode *t );
    static int height( BinaryNode *t );

    void printPreOrder( ) const;
    void printPostOrder( ) const;
    void printInOrder( ) const;

    BinaryNode *duplicate( ) const;

  public:   // To keep things simple
    Object      element;
    BinaryNode *left;
    BinaryNode *right;
};

template <class Object>
class TreeIterator;


// BinaryTree class; stores a binary tree.
//
// CONSTRUCTION: with (a) no parameters or (b) an object to
//    be placed in the root of a one-element tree.
//
// *******************PUBLIC OPERATIONS**********************
// Various tree traversals, size, height, isEmpty, makeEmpty.
// Also, the following tricky method:
// void merge( Object root, BinaryTree t1, BinaryTree t2 )
//                        --> Construct a new tree
// *******************ERRORS*********************************
// Error message printed for illegal merges.

template <class Object>
class BinaryTree
{
  public:
    BinaryTree( ) : root( NULL ) { }
    BinaryTree( const Object & rootItem )
      : root( new Node( rootItem ) ) { }
    BinaryTree( const BinaryTree & rhs )
      : root( NULL ) { *this = rhs; }

    ~BinaryTree( )
      { makeEmpty( ); }

    const BinaryTree & operator= ( const BinaryTree & rhs );

      // Recursive traversals, with printing
    void printPreOrder( ) const
      { if( root != NULL ) root->printPreOrder( ); }    
    void printInOrder( ) const
      { if( root != NULL ) root->printInOrder( ); }    
    void printPostOrder( ) const
      { if( root != NULL ) root->printPostOrder( ); }    
     
    void makeEmpty( )
      { makeEmpty( root ); } 
    bool isEmpty( ) const
      { return root == NULL; }

      // Combine t1 and t2
    void merge( const Object & rootItem, BinaryTree & t1, BinaryTree & t2 );

    int size( ) const
      { return Node::size( root ); }
    int height( ) const
      { return Node::height( root ); }
    
  private:
    typedef BinaryNode<Object> Node;
    Node *root;

    friend class TreeIterator<Object>;
    void makeEmpty( BinaryNode<Object> * & t );
};

// Constructor.
template <class Object>
BinaryNode<Object>::BinaryNode( const Object & theElement,
                                BinaryNode *lt, BinaryNode *rt )
  : element( theElement ), left( lt ), right( rt )
{ 
}

// Return size of tree rooted at t.
template <class Object>
int BinaryNode<Object>::size( BinaryNode<Object> * t )
{
    if( t == NULL )
        return 0;
    else
        return 1 + size( t->left ) + size( t->right );
}

#define max MAX

template <class Comparable>
Comparable max( const Comparable & a, const Comparable & b )
{
    return a > b ? a : b;
}

// Return height of tree rooted at t.
template <class Object>
int BinaryNode<Object>::height( BinaryNode<Object> * t )
{
    if( t == NULL )
        return -1;
    else
        return 1 + max( height( t->left ), height( t->right ) );
}

#undef max

// Print the tree rooted at current node using preorder traversal.
template <class Object>
void BinaryNode<Object>::printPreOrder( ) const
{
    cout << element << endl;                  // Node
    if( left != NULL )
        left->printPreOrder( );               // Left
    if( right != NULL )
        right->printPreOrder( );              // Right
}

// Print the tree rooted at current node using postorder traversal.
template <class Object>
void BinaryNode<Object>::printPostOrder( ) const
{
    if( left != NULL )                        // Left
        left->printPostOrder( );
    if( right != NULL )                       // Right
        right->printPostOrder( );
    cout << element << endl;                  // Node
}

// Print the tree rooted at current node using inorder traversal.
template <class Object>
void BinaryNode<Object>::printInOrder( ) const
{
    if( left != NULL )                        // Left
        left->printInOrder( );
    cout << element << endl;                  // Node
    if( right != NULL )
        right->printInOrder( );               // Right
}

// Return a pointer to a node that is the root of a
// duplicate of the tree rooted at the current node.
template <class Object>
BinaryNode<Object> * BinaryNode<Object>::duplicate( ) const
{
    BinaryNode<Object> *root =
                         new BinaryNode<Object>( element );

    if( left != NULL )            // If there's a left subtree
        root->left = left->duplicate( );   // Duplicate; attach
    if( right != NULL )           // If there's a right subtree
        root->right = right->duplicate( ); // Duplicate; attach

    return root;                     // Return resulting tree
}

// Deep copy.
template <class Object>
const BinaryTree<Object> &
BinaryTree<Object>::operator= ( const BinaryTree<Object> & rhs )
{
    if( this != &rhs )
    {
        makeEmpty( );
        if( rhs.root != NULL )
            root = rhs.root->duplicate( );
    }

    return *this;
}

// Merge routine for BinaryTree class.
// Forms a new tree from rootItem, t1 and t2.
// Does not allow t1 and t2 to be the same.
// Correctly handles other aliasing conditions.
template <class Object>
void BinaryTree<Object>::merge( const Object &  rootItem,
                         BinaryTree<Object> & t1, BinaryTree<Object> & t2 )
{
    if( t1.root == t2.root && t1.root != NULL )
    { 
        cerr << "Cannot merge a tree with itself; merge aborted." << endl;
        return;
    }

    Node *oldRoot = root;   // Save old root

      // Allocate new node
    root = new Node( rootItem, t1.root, t2.root );

      // Deallocate nodes in the original tree
    if( this != &t1 && this != &t2 )
        makeEmpty( oldRoot );

      // Ensure that every node is in one tree
    if( this != &t1 )
        t1.root = NULL;
    if( this != &t2 )
        t2.root = NULL;
}

// Make tree rooted at t empty, freeing nodes, and setting t to NULL.
template <class Object>
void BinaryTree<Object>::makeEmpty( BinaryNode<Object> * & t )
{
    if( t != NULL )
    {
        makeEmpty( t->left );
        makeEmpty( t->right );
        delete t;
        t = NULL;
    }
}
#endif

Open in new window

>> Error:       1      IntelliSense: expression must have class type      c:\users\owner\documents\visual studio 2010\projects\binarytree\binarytree\main.cpp      45      6      BinaryTree

And which line does that error refer to ?
Line 45: In Main Class

 ptrStack.push(newNode);
To address that, change

      Stack<BinaryNode<char>*> ptrStack();

to

      Stack<BinaryNode<char>*> ptrStack;

Then you will face the next error, which is

error C2664: 'Stack<Object>::push' : cannot convert parameter
1 from 'BinaryNode<Object>' to 'BinaryNode<Object> &'

(scratching my head regarding this one at the moment ;o)
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial