此回是针对上回所设计方案的扩展,下面将会演示
(1)如何增加计算表达式的值的功能
(2)如何增加新的节点类型(已经有表示单个数、一元操作符、二元操作符的节点类型Int_node\Unary_node\Binary_node,将演示如何增加三元操作符(Ternary_node))
完整代码如下:
#include <iostream> #include <string> using namespace std; class Expr_node { friend class Expr; //友元类可以被继承 int use; //引用计数 public: virtual void print(ostream&) const = 0; public: Expr_node():use(1) {} virtual ~Expr_node() {} virtual int eval() const = 0; }; class Expr //句柄类 { friend ostream& operator<<(ostream &o, const Expr &e); private: Expr_node *p; //指向基类的指针 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!错误的一元操作符"; } }; 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! 错误的二元操作符!"; } }; 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; }
运行结果如下:
((-5)*(3+4))=-3
(5-(0?1:2))=3