Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Error: Expression must have a class type

Posted on 2011-02-28
7
Medium Priority
?
2,943 Views
Last Modified: 2012-05-11
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

0
Comment
Question by:brich744
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
7 Comments
 
LVL 53

Expert Comment

by:Infinity08
ID: 35000369
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 ?
0
 

Author Comment

by:brich744
ID: 35000416
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

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 35000457
>> 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 ?
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:brich744
ID: 35000473
Line 45: In Main Class

 ptrStack.push(newNode);
0
 
LVL 86

Expert Comment

by:jkr
ID: 35000530
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)
0
 
LVL 86

Accepted Solution

by:
jkr earned 1000 total points
ID: 35000577
Ah.... you have a

      Stack<BinaryNode<char>*> ptrStack;

and are trying to 'push()' a

         BinaryNode<char> newNode(*tokenPtr);

Shouldn't that more be like the following?
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

0
 
LVL 53

Assisted Solution

by:Infinity08
Infinity08 earned 1000 total points
ID: 35000586
Ah, I see. The mention of BinaryTree in the error message was a bit confusing, because BinaryTree was never used in main.

But the problem is that :

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

defines ptrStack as a function that takes no arguments, and returns a Stack<BinaryNode<char>*>.

Use this instead in order not to confuse the compiler :

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

or just :

        Stack<BinaryNode<char>*> ptrStack;
0

Featured Post

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…

722 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question