《c++沉思录》-day3

本文介绍了一种使用面向对象的方法来解析数学表达式的方案。通过定义一个基础的节点类及派生类,如整数节点、一元运算节点和二元运算节点,实现了表达式的树形结构,并利用句柄类来管理这些节点。文章详细展示了如何构建此类表达式树并进行输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天看到第八章 一个面向对象的程序范例

 

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<<")";}
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值