This is an extension of the last design scheme. The following will show
(1) how to increase the function of calculating the expression value
(2) how to add a new node type (Int_node \ Unary_node \ Binary_node, which represents a single number, a one-dimensional operator, and a binary operator, will demonstrate how to add a three-element operator (Ternary_node ))
The complete code is as follows:
# Include <iostream>
# Include <string>
Using namespace std;
Class Expr_node
{
Friend class Expr; // The friend Meta class can be inherited.
Int use; // reference count
Public:
Virtual void print (ostream &) const = 0;
Public:
Expr_node (): use (1 ){}
Virtual ~ Expr_node (){}
Virtual int eval () const = 0;
};
Class Expr // handle class
{
Friend ostream & operator <(ostream & o, const Expr & e );
Private:
Expr_node * p; // pointer to the base class
Public:
Expr (int n );
Expr (const string & op, Expr t );
Expr (const string & op, Expr left, Expr right );
Expr (const string & op, Expr left, Expr middle, Expr right );
Expr (const Expr & t );
Expr & operator = (const Expr &);
~ Expr ()
{
If (-- p-> use = 0)
Delete p;
}
Int eval () const
{
Return p-> eval ();
}
};
Class Int_node: public Expr_node
{
Private:
Int n;
Public:
Int_node (int k): n (k ){}
Void print (ostream & o) const
{
O <n;
}
Int eval () const {return n ;}
};
Class Unary_node: public Expr_node
{
Private:
// Friend class Expr;
String op;
Expr opnd;
Public:
Unary_node (const string & a, Expr B): op (a), opnd (B ){}
Void print (ostream & o) const
{
O <"(" <op <opnd <")";
}
Int eval () const
{
If (op = "-")
Return-opnd. eval ();
Throw "error! Incorrect unary operator ";
}
};
Class Binary_node: public Expr_node
{
Private:
// Friend class Expr;
String op;
Expr left;
Expr right;
Public:
Binary_node (const string & a, Expr B, Expr c): op (a), left (B), right (c ){}
Void print (ostream & o) const
{
O <"(" <left <op <right <")";
}
Int eval () const
{
Int op1 = left. eval ();
Int op2 = right. eval ();
If (op = "-") return op1-op2;
If (op = "+") return op1 + op2;
If (op = "*") return op1 * op2;
If (op = "/") return op1/op2;
Throw "error! Incorrect binary operator! ";
}
};
Class Ternary_node: public Expr_node
{
Private:
String op;
Expr left;
Expr middle;
Expr right;
Public:
Ternary_node (const string & a, Expr B, Expr c, Expr d): op (a), left (B), middle (c), right (d ){}
Void print (ostream & o) const
{
O <"(" <left <"? "<Middle <": "<right <")";
}
Int eval () const
{
If (left. eval ())
Return middle. eval ();
Else
Return right. eval ();
}
};
Expr: Expr (int n) {p = new Int_node (n );}
Expr: Expr (const string & op, Expr t) {p = new Unary_node (op, t );}
Expr: Expr (const string & op, Expr left, Expr right) {p = new Binary_node (op, left, right );}
Expr: Expr (const string & op, Expr left, Expr middle, Expr right) {p = new Ternary_node (op, left, middle, right );}
Expr: Expr (const Expr & t) {p = t. p; ++ p-> use ;}
Expr & Expr: operator = (const Expr & rhs)
{
Rhs. p-> use ++;
If (-- p-> use = 0)
Delete p;
P = rhs. p;
Return * this;
}
Ostream & operator <(ostream & o, const Expr & e)
{
E. p-> print (o );
Return o;
}
Void main ()
{
Expr t = Expr ("*",
Expr ("-", Expr (5 )),
Expr ("+", Expr (3), Expr (4 )));
Cout <t <"=" <t. eval () <endl;
Expr t2 = Expr ("-", Expr (5), Expr ("? : ", Expr (0), Expr (1), Expr (2 )));
Cout <t2 <"=" <t2.eval () <endl;
}
The running result is as follows:
(-5) * (3 + 4) =-3
(5-(0? 2) = 3
Author: yucan1001