面向对象的程序范例(二)
功能:显示+计算
过程:在前者的基础上添加计算的代码
特点:由于已经精确地建模过,所以几乎不用改动原有的代码,可以直接添加新的部分
代码:
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