• Welcome to Valhalla Legends Archive.
 

Abstract class

Started by K, November 20, 2003, 04:17 PM

Previous topic - Next topic

K

I'm having a problem with this:
I'm writing an expression parser for a class project; I thought it would be a swell idea to have an abstract (binary) operator class which other classes implement.  This is shown below.
Problems arise when I try to do something like this, however:

// should return an instance of the addition operator
Operator o = Operator::Create('+');


The error is this: "Abstract classes cannot be instatiated." I know what this means, but I never tried to do this; Create() calls the AdditionOperator constructor, as shown below.  

In a vain effort to simply avoid my problems, I made the Operator class nonabstract, but with virtual functions that didn't do anything.  However, when I debug and look at what is returned by Operator::Create(), the return object's function virtual function tables all point to the Operator functions instead of the derrived class!

Any help?


class Operator
{
public:
   static Operator Create(char symbol);

   virtual double Execute(double lh, double rh) const = 0;
   virtual PRECEDENCE Precedence() const = 0;
   virtual std::string ToString() const = 0;
   bool operator<(const Operator& o) const
   {
      return (Precedence() < o.Precedence());
   }
   bool operator>(const Operator& o) const
   {
      return (Precedence() > o.Precedence());
   }
};

Operator Operator::Create(char symbol)
{
   switch(symbol)
   {
   case '(':
      return ParenthesesOperator(false);
   case ')':
      return ParenthesesOperator(true);
   case '^':
      return PowerOperator();
   case '*':
      return MultiplicationOperator();
   case '/':
      return DivisionOperator();
   case '+':
      return AdditionOperator();
   case '-':
      return SubtractionOperator();
   default:
      throw "Error: unknown operator.";
   }
}


class PowerOperator : public Operator
{
public:
   double Execute(double lh, double rh) const
   {
      return std::pow(lh, rh);
   }

   PRECEDENCE Precedence() const
   {
      return PRECEDENCE_HIGH;
   }

   std::string ToString() const
   {
      return "^";
   }

};

Eibro

Operator Operator::Create(char symbol)
{
  switch(symbol)
  {
  case '(':
     return ParenthesesOperator(false);
  case ')':
     return ParenthesesOperator(true);
  case '^':
     return PowerOperator();
  case '*':
     return MultiplicationOperator();
  case '/':
     return DivisionOperator();
  case '+':
     return AdditionOperator();
  case '-':
     return SubtractionOperator();
  default:
     throw "Error: unknown operator.";
  }
}
As far as I can see, you're essentially shredding whatever derived-object you return. Try returning a reference or pointer instead.

http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.8
http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.20
Eibro of Yeti Lovers.

K

That's what I thought.  I guess I'll create an object factory that returns a pointer and deletes all the pointers when they go out of scope.