面向对象编程的3个要素:数据抽象、继承及动态绑定。这个例程非常完整的展示了这3个要素。 程序要做的内容就是要将这个算术表达树输出,即得到:(-5)*(3+4) #include <string> #include <iostream> using namespace std; class Expr_node { friend ostream& operator<<(ostream& o,const Expr_node e)//友元函数重载输出操作符 { e.print(o); return o; } friend class Expr; int use; public: Expr_node(): use(1) {} ///Expr_node的子类在执行自己的构造函数时,会调用父类的构造函数 ///在里这个父类的构造函数为子类其进行引用计数 virtual void print(ostream&) const = 0;虚函数,在其子类中进行重新定义,运行时动态绑定 virtual ~Expr_node(){} ///保证在删除由Expr_node*指针指向的对象时能够调用到正确的派生类析构造函数 }; class Expr { friend ostream& operator<<(ostream& o,const Expr& t) { t.p->print(o); return o; } Expr_node *p; public: Expr(int); Expr(const string&,Expr); Expr(const string&,Expr,Expr); Expr(const Expr& t){ p=t.p; ++p->use; } Expr& operator=(const Expr&); ~Expr(){if(--p->use==0) delete p;} }; class Int_node: public Expr_node { friend class Expr; int n; Int_node(int k): n(k){} void print(ostream& o)const { o<<n; } }; class Unary_node: public Expr_node { friend class Expr; string op; Expr opnd; Unary_node(const string& a,Expr b) : op(a),opnd(b){} void print(ostream& o) const { o<< "(" << op << opnd <<")"; } }; class Binary_node: public Expr_node { friend class Expr; string op; Expr left; Expr right; Binary_node(const string& a,Expr b,Expr c):op(a),left(b),right(c) {} void print(ostream& o) const { o<< "(" << left << op << right <<")" ; } }; 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::operator =(const Expr& rhs) { rhs.p->use++; if(--p->use==0) delete p; p=rhs.p; return *this; } int main(void) { Expr t = Expr("*",Expr("-",5),Expr("+",3,4)); cout<<t<<endl; t = Expr("*",t,t); cout<<t<<endl; return 0; }