在c++沉思录举了一个表达式树的例子,将例如(-5)*(3+4)的式子表示成树的形式。可以通过如下形式:
Expr t = Expr("*", Expr("-", 5), Expr("+", 3, 4));
cout<<t<<" = "<<t.eval()<<endl;
创建树并将树打印出来。
这个程序主要用于理解动态绑定和句柄,程序实现代码如下:
#include
<
iostream
>
#include < string >
/*
所有节点类型的父类
*/
class Expr_node{
// friend ostream& operator<<(ostream&, const Expr&);
friend class Expr;
int use;
protected :
Expr_node():use( 1 ){}
virtual int eval() const = 0 ;
public :
virtual void print(ostream & ) const = 0 ; // 书中这个方法是protected修饰的,但是放在那里会报错
virtual ~ Expr_node(){}
};
/* *
句柄类
*/
class Expr{
// 重载操作符
friend ostream & operator << (ostream & , const Expr & );
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;}
int eval() const { return p -> eval();}
// ostream& operator<<(ostream&, const Expr&)const;
};
class Int_node: public Expr_node{
friend class Expr;
int n;
Int_node( int k):n(k){}
void print(ostream & o) const {o << n;}
int eval() const { return 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 << " ) " ;}
int eval() const ;
};
int
Unary_node::eval() const
{
if (op == " - " )
return - opnd.eval();
throw " error,bad op " + op + " in unarnode " ;
}
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){}
int eval() const ;
void print(ostream & o) const
{
o << " ( " << left << op << right << " ) " ;
}
};
int
Binary_node::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 == " / " && op2 != 0 ) return op1 / op2;
throw " error, bad op " + op + " in binarynode " ;
}
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 ;
}
ostream &
operator << (ostream & o, const Expr & t)
{
t.p -> print(o);
return o;
}
int main()
{
Expr t = Expr( " * " , Expr( " - " , 5 ), Expr( " + " , 3 , 4 ));
cout << t << " = " << t.eval() << endl;
}
#include < string >
/*
所有节点类型的父类
*/
class Expr_node{
// friend ostream& operator<<(ostream&, const Expr&);
friend class Expr;
int use;
protected :
Expr_node():use( 1 ){}
virtual int eval() const = 0 ;
public :
virtual void print(ostream & ) const = 0 ; // 书中这个方法是protected修饰的,但是放在那里会报错
virtual ~ Expr_node(){}
};
/* *
句柄类
*/
class Expr{
// 重载操作符
friend ostream & operator << (ostream & , const Expr & );
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;}
int eval() const { return p -> eval();}
// ostream& operator<<(ostream&, const Expr&)const;
};
class Int_node: public Expr_node{
friend class Expr;
int n;
Int_node( int k):n(k){}
void print(ostream & o) const {o << n;}
int eval() const { return 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 << " ) " ;}
int eval() const ;
};
int
Unary_node::eval() const
{
if (op == " - " )
return - opnd.eval();
throw " error,bad op " + op + " in unarnode " ;
}
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){}
int eval() const ;
void print(ostream & o) const
{
o << " ( " << left << op << right << " ) " ;
}
};
int
Binary_node::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 == " / " && op2 != 0 ) return op1 / op2;
throw " error, bad op " + op + " in binarynode " ;
}
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 ;
}
ostream &
operator << (ostream & o, const Expr & t)
{
t.p -> print(o);
return o;
}
int main()
{
Expr t = Expr( " * " , Expr( " - " , 5 ), Expr( " + " , 3 , 4 ));
cout << t << " = " << t.eval() << endl;
}