Valhalla Legends Forums Archive | C/C++ Programming | Abstract class

AuthorMessageTime
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:
[code]
// should return an instance of the addition operator
Operator o = Operator::Create('+');
[/code]

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?

[code]
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 "^";
   }

};
[/code]
November 20, 2003, 10:17 PM
Eibro
[code]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.";
}
}[/code]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
November 20, 2003, 10:29 PM
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.
November 20, 2003, 10:51 PM

Search