面向对象的程序范例(二)

功能:显示+计算

过程:在前者的基础上添加计算的代码

特点:由于已经精确地建模过,所以几乎不用改动原有的代码,可以直接添加新的部分

代码:

  1 #include <iostream>
  2 using namespace std;
  3 
  4 class Expr_node;
  5 
  6 // 句柄类
  7 class Expr
  8 {
  9     friend ostream& operator<< (ostream& o, const Expr& t);
 10     Expr_node* p;
 11 public:
 12     Expr():p(0){}
 13     Expr(int n);
 14     Expr(const string& op, const Expr& t);
 15     Expr(const string& op, const Expr& left, const Expr& right);
 16     Expr(const Expr& t);
 17     Expr& operator=(const Expr&);
 18     int eval() const;
 19     ~Expr();
 20 };
 21 
 22 // 用于派生实际类型的公共基类,表示“结点”
 23 class Expr_node
 24 {
 25     friend class Expr;
 26     friend ostream& operator<< (ostream& o, const Expr& t);
 27     int use;
 28 protected:
 29     Expr_node():use(1){}
 30     virtual ~Expr_node() {};
 31     virtual void print(ostream&)const=0;
 32     virtual int eval() const=0;
 33 };
 34 
 35 // 存放数值的子类
 36 class Int_node:public Expr_node
 37 {
 38     friend class Expr;
 39     int n;
 40     Int_node(int k):n(k){}
 41     void print(ostream& o)const{o<<n;}
 42     int eval() const {return n;}
 43 };
 44 
 45 // 存放符号数的类
 46 class Unary_node:public Expr_node
 47 {
 48     friend class Expr;
 49     string op;
 50     Expr opnd;
 51     Unary_node(const string& a, const Expr& b):op(a),opnd(b){}
 52     void print(ostream& o)const{o<<"("<<op<<opnd<<")";}
 53     int eval() const {if (op=="-") return -opnd.eval(); throw "error, bad op "+op+" in Unary_node";}
 54 };
 55 
 56 // 存放符号和左右表达式的子类
 57 class Binary_node:public Expr_node
 58 {
 59     friend class Expr;
 60     string op;
 61     Expr left;
 62     Expr right;
 63     Binary_node(const string& a, const Expr& b, const Expr& c):op(a),left(b),right(c){}
 64     void print(ostream& o)const{o<<"("<<left<<op<<right<<")";}
 65     int eval() const
 66     {
 67         int l = left.eval();
 68         int r = right.eval();
 69         int result;
 70         if (op=="-") result = l - r;
 71         else if (op=="+") result = l + r;
 72         else if (op=="/" && r!=0) result = l / r;
 73         else if (op=="*") result = l * r;
 74         else throw "error, bad op "+op+" in Binary_node";
 75         return result;
 76     }
 77 };
 78 
 79 Expr::Expr(int n){p=new Int_node(n);}
 80 Expr::Expr(const string& op, const Expr& t){p = new Unary_node(op,t);}
 81 Expr::Expr(const string& op, const Expr& left, const Expr& right){p = new Binary_node(op,left,right);}
 82 Expr::Expr(const Expr& t):p(t.p){++(p->use);}
 83 Expr& Expr::operator=(const Expr& rhs)
 84 {
 85     rhs.p->use++;
 86     if (p&&--(p->use)==0)
 87         delete p;
 88     p = rhs.p;
 89     return *this;
 90 }
 91 int Expr::eval() const
 92 {
 93     return p->eval();
 94 }
 95 Expr::~Expr() {if (--p->use==0) delete p;}
 96 
 97 ostream& operator<< (ostream& o, const Expr& t)
 98 {
 99     t.p->print(o);
100     return o;
101 }
102 
103 int main()
104 {
105     Expr t("*", Expr("-", 5), Expr("+", 3, 4));
106     cout<<t<<" = "<<t.eval()<<endl;
107     t = Expr("*", t, t);
108     cout<<t<<" = "<<t.eval()<<endl;
109     Expr u;
110     u = Expr("*", t, t);
111     cout<<u<<" = "<<u.eval()<<endl;
112     return 0;
113 }

结果:

  ((-5)*(3+4)) = -35

  (((-5)*(3+4))*((-5)*(3+4))) = 1225

  ((((-5)*(3+4))*((-5)*(3+4)))*(((-5)*(3+4))*((-5)*(3+4)))) = 1500625

面向对象的程序范例(二)

上一篇:实战三:根据父母的身高预测儿子的身高


下一篇:int string 输出标准格式