面向对象的程序范例(一)
功能:打印表达式
技术:句柄、继承
代码
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 ~Expr(); 19 }; 20 21 // 用于派生实际类型的公共基类,表示“结点” 22 class Expr_node 23 { 24 friend class Expr; 25 int use; 26 protected: 27 Expr_node():use(1){} 28 virtual ~Expr_node() {}; 29 public: 30 virtual void print(ostream&)const=0; 31 }; 32 33 // 存放数值的子类 34 class Int_node:public Expr_node 35 { 36 friend class Expr; 37 int n; 38 Int_node(int k):n(k){} 39 public: 40 void print(ostream& o)const{o<<n;} 41 }; 42 43 // 存放符号数的类 44 class Unary_node:public Expr_node 45 { 46 friend class Expr; 47 string op; 48 Expr opnd; 49 Unary_node(const string& a, const Expr& b):op(a),opnd(b){} 50 public: 51 void print(ostream& o)const{o<<"("<<op<<opnd<<")";} 52 }; 53 54 // 存放符号和左右表达式的子类 55 class Binary_node:public Expr_node 56 { 57 friend class Expr; 58 string op; 59 Expr left; 60 Expr right; 61 Binary_node(const string& a, const Expr& b, const Expr& c):op(a),left(b),right(c){} 62 public: 63 void print(ostream& o)const{o<<"("<<left<<op<<right<<")";} 64 }; 65 66 Expr::Expr(int n){p=new Int_node(n);} 67 Expr::Expr(const string& op, const Expr& t){p = new Unary_node(op,t);} 68 Expr::Expr(const string& op, const Expr& left, const Expr& right){p = new Binary_node(op,left,right);} 69 Expr::Expr(const Expr& t):p(t.p){++(p->use);} 70 Expr& Expr::operator=(const Expr& rhs) 71 { 72 rhs.p->use++; 73 if (p&&--(p->use)==0) 74 delete p; 75 p = rhs.p; 76 return *this; 77 } 78 Expr::~Expr() {if (--p->use==0) delete p;} 79 80 ostream& operator<< (ostream& o, const Expr& t) 81 { 82 t.p->print(o); 83 return o; 84 } 85 86 int main() 87 { 88 Expr t("*", Expr("-", 5), Expr("+", 3, 4)); 89 cout<<t<<endl; 90 t = Expr("*", t, t); 91 cout<<t<<endl; 92 Expr u; 93 u = Expr("*", t, t); 94 cout<<u<<endl; 95 return 0; 96 }
或:将 '<<' 运算赋予Expr_node的友元属性,并取消print的public、改为private,来隐藏print
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 ~Expr(); 19 }; 20 21 // 用于派生实际类型的公共基类,表示“结点” 22 class Expr_node 23 { 24 friend class Expr; 25 friend ostream& operator<< (ostream& o, const Expr& t); 26 int use; 27 protected: 28 Expr_node():use(1){} 29 virtual ~Expr_node() {}; 30 virtual void print(ostream&)const=0; 31 }; 32 33 // 存放数值的子类 34 class Int_node:public Expr_node 35 { 36 friend class Expr; 37 int n; 38 Int_node(int k):n(k){} 39 void print(ostream& o)const{o<<n;} 40 }; 41 42 // 存放符号数的类 43 class Unary_node:public Expr_node 44 { 45 friend class Expr; 46 string op; 47 Expr opnd; 48 Unary_node(const string& a, const Expr& b):op(a),opnd(b){} 49 void print(ostream& o)const{o<<"("<<op<<opnd<<")";} 50 }; 51 52 // 存放符号和左右表达式的子类 53 class Binary_node:public Expr_node 54 { 55 friend class Expr; 56 string op; 57 Expr left; 58 Expr right; 59 Binary_node(const string& a, const Expr& b, const Expr& c):op(a),left(b),right(c){} 60 void print(ostream& o)const{o<<"("<<left<<op<<right<<")";} 61 }; 62 63 Expr::Expr(int n){p=new Int_node(n);} 64 Expr::Expr(const string& op, const Expr& t){p = new Unary_node(op,t);} 65 Expr::Expr(const string& op, const Expr& left, const Expr& right){p = new Binary_node(op,left,right);} 66 Expr::Expr(const Expr& t):p(t.p){++(p->use);} 67 Expr& Expr::operator=(const Expr& rhs) 68 { 69 rhs.p->use++; 70 if (p&&--(p->use)==0) 71 delete p; 72 p = rhs.p; 73 return *this; 74 } 75 Expr::~Expr() {if (--p->use==0) delete p;} 76 77 ostream& operator<< (ostream& o, const Expr& t) 78 { 79 t.p->print(o); 80 return o; 81 } 82 83 int main() 84 { 85 Expr t("*", Expr("-", 5), Expr("+", 3, 4)); 86 cout<<t<<endl; 87 t = Expr("*", t, t); 88 cout<<t<<endl; 89 Expr u; 90 u = Expr("*", t, t); 91 cout<<u<<endl; 92 return 0; 93 }
示意图:
结果:
((-5)*(3+4))
((((-5)*(3+4)))*(((-5)*(3+4))))
((((-5)*(3+4))*((-5)*(3+4)))*(((-5)*(3+4))*((-5)*(3+4))))