Author | Message | Time |
---|---|---|
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 |