今天看到第八章 一个面向对象的程序范例
1问题描述
我们希望将四则运算的表达式来调用合适的函数来创建一个数
(-5)*(3+4)
为
*
/ /
- +
/ / /
5 3 4
这样的树
2面向对象的解决方案
我们需要一个类来表示节点这个概念,这个类并不是一个具体的节点,我们所有的实际的类型都将从这个公共的基类派生出来。
class Expr_node {
friend ostream& operator<< (ostream&,const Expt_node);
protected:
virtual void print(ostream&) const=0;
virtual ~Expr_node();
}
我们用<<来输出操作符来打印表达式树,东财绑定只适用于成员函数,所以我们定义可一个虚函数print,可以调用他来实现工作,我们不用print那么就设置为protect,把operator<<设置为友元。
我们定义输出操作符
ostream& operator <<(ostream& o,const Expt_node& e)
{
e.print(o);
return o;
}
下面生成具体的类
class int_node:public expt_node{
friend class Expt;
int n;
Int_node(int k):n(k){}
void print(ostream& o) const {o<<n;}
};
3句柄类
我们建立一个句柄类来管理指针,Expt是一个句柄类,表示一个边,可以用他来隐藏Expt_node继承层次,Expt的用户不会直接看到Expt_node
class Expr {
friend Ostream& operator<<(ostream&,const Expr&);
Expr_node* p;
pbulic:
Expr(int);
Expr(const string&,Expr);
Expr(const string&,Expr,Expr);
Expr(const Expr&);
Expr& operator=(const Expr);
~Expr() {delete p;}
Expr(const Expr& t){p=t.p;++p->use;}
~wxpr(){if(--p->use==0) delete p;}
Expr& operator=(const Expr& t){
t.p->use++;
if(--p->use==0)
delete p;
p=t.p
return *this;
}
Expr::Expr(int n) {
p=new Int_node(n);
}
Expr::Expr(xonst Steing& op,Expr t) {
p=new Umary_node(op,t);
}
Expr::Expr(const String& op,Expr left,Expr right) {
p=new Binary_node(op,left,right);
}
避免复制的常用方法就是让每一个Expr_node包含一个引用计数,指明同时有多少Expr指向一个Expr-node,如果能避免复制下层的Expr_node会更有效率
class Expr_node {
friend ostream& operator<<(ostream&,const expr&);
friend class Expr;
int use;
protected:
Expr_node():use(1){}
virtual void print(ostream&) const=0;
virtual ~Expr_node(){}
};
class Unary_node;public Expr_node{
friend class Expr;
String op;
Expr opnd; //将Expr_node改为Expr
Expr_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_node* left;,因加入句柄而改为现在语句
Expr right;
Expr_node(const String& a,Expr b,Expr c):op(a),left(b),right(c){}
void print(ostream& o) const
{o<<"("<<*left<<op<<*right<<")";}
};