表达式求值:面向对象版本

news/2024/7/20 15:43:37 标签: 内存管理, c/c++
 c++沉思录中的一个例子.
 
 
思路:
由图所示, 将节点的概念用类表示.
相同点:每个节点存储一个值以及一些节点   继承
不同点:值的种类, 存储节点的数量               动态绑定
 
进一步:
3种节点类型 
1.只有一个数值, 无子节点
2.一元运算符, 一个子节点
3.二元运算符, 两个子节点
针对每种类型的节点,都需要进行打印动作
不同的事物,具有相同的界面(接口), 意味着需要使用动态绑定.
 
下一步:
考虑到3种节点类型之间均没有 "is-a"的关系, 所以需要创建公共抽象基类ExprNode
class ExprNode
{
	friend std::ostream& operator<<(std::ostream&, const ExprNode&);
protected:	
	virtual ~ExprNode(){};
	virtual void Print(std::ostream&) const = 0;
};
 
std::ostream&
operator<<(std::ostreamosconst ExprNodenode)
{
	node.Print(os);
	return os;
}

继续创建其他节点类:
class NumbericNode : public ExprNode
{
protected:
	NumbericNode(int val): value_(val) {}
	void Print(std::ostreamosconst override
	{
		os << value_;
	}
 
private:
	int value_;
};
 
class UnaryNode : public ExprNode
{
protected:
	UnaryNode(const char _operatorExprNode_expression)
		:operator_(_operator), expression_(_expression)
	{
	}
 
	~UnaryNode()
	{
	}
 
	void Print(std::ostreamosconst override
	{
		os << "(" << operator_ << *expression_ << ")";
	}	
 
private:
	ExprNode* expression_;
	char operator_;
};
 
class BinaryNode : public ExprNode
{
protected:
	BinaryNode(const char _operatorExprNodeleftExprNoderight)
		:operator_(_operator), left_(left), right_(right)
	{
	}
 
	~BinaryNode()
	{
	}
 
	void Print(std::ostreamosconst override
	{
		os << "(" << *left_ << operator_ << *right_ << ")";
	}
 
 
private:
	ExprNode* left_;
	ExprNode* right_;
	char operator_;
};
 
  
在创建表达式节点类时,注意到客户端(使用者)并不知晓存在节点类. 所以可以将节点子类的构造函数声明为保护成员.同时将Expr设为所有子类的友元类
以便访问节点类的构造函数.
继续:
此时, 如何构造表达式树呢? 我们发现节点类只是对原始问题中的圆圈建模, 而丢弃了箭头. 那么对其建模就创建了Expr类, 来构造表达式树
但未了减少用户使用的复杂度, 用户不再关心内存管理的问题.即创建每个节点类型实例. 所以将Expr设计为句柄类,对节点实例进行内存管理.同时也起到对用户隐藏ExprNode及其派生类的继承层次和隐藏具体实现
修改完成后的代码版本
源码

转载于:https://www.cnblogs.com/neking/archive/2013/06/09/3128145.html


http://www.niftyadmin.cn/n/1050583.html

相关文章

Eclipse初次java开发问题总结-1

项目需要&#xff0c;使用Eclipse初次java开发&#xff0c;过程中遇到很多问题&#xff0c;有的问题可能很低级&#xff0c;这里做个简单的总结&#xff0c;怕忘记&#xff1a; 1、Dyanamic Web Project工程引用普通java工程的类&#xff0c;可能会出现NoClassDefFoundError问题…

cnetos 下 rar 解压

第一步&#xff1a;http://www.rarlab.com/rar/rarlinux-x64-5.3.0.tar.gz 下载 文件 或 wget http://www.rarlab.com/rar/rarlinux-x64-5.3.0.tar.gz[笔者被墙你懂得] 默认下载到当前目录 第二步 tar -zxvf tar -zxvf rarlinux-x64-5.3.0.tar.gz cd rar make 测试&#xff1…

二叉树(1)——五叉树的定义和递归实现

定义 最多有两棵子树的有序树&#xff0c;称为二叉树。二叉树是一种特殊的树。 递归定义&#xff1a;二叉树是n(n>0)个有限结点构成的集合。N0称为空二叉树&#xff1b;n>0的二叉树由一个根结点和两互不相交的&#xff0c;分别称为左子树和右子树的二叉树构成。 二叉树中…

sgu 133 Border

题意&#xff1a;完全被其它区间包括在内的区间有几个&#xff1f; 类似将前面元素放入优先队列的方法。先将元素按pair排序。因为数据中所有的左右端点(记为[x,y]&#xff09;都不同。因此循环到第i个元素时&#xff0c;x比它小的都在它左边&#xff0c;因此它只能被左边的元素…

Scott Hanselman's 推荐的的实用工具集合(2011版)

Scott Hanselman活跃于.NET社区&#xff0c;这篇文章来自于它的工具列表&#xff0c;地址是http://www.hanselman.com/tools .NET开发人员应该收藏的工具 LINQPad 快速理解和构建Linq查询&#xff0c;也可用于生成Linq表达式的实用工具 Microsoft Web Platform Installer 如果…

Salesforce 开发整理(八)PDF打印相关

一&#xff1a;基础设置 Salesforce中的PDF页面本质上还是Visualforce[简称VF]页面&#xff0c;所以只需要给VF页面加上一个属性[renderAs"pdf"] 即可生成一个PDF页面 1 <apex:page renderAs"pdf"> 2 this is a Visualforce page!!! 这是一个VF页…

tomcat_garbage collection_log(垃圾回收日志)参数设置 待整理

这是tomcat下面catalina.bat文件的部分代码 echo off if "%OS%" "Windows_NT" setlocal set CATALINA_HOMED:\Tomcat5_websearchset HEAP-Xms4096m -Xmx4096m set PERMANENT_G-XX:PermSize128m -XX:MaxPermSize128m set YOUNG_G-Xmn600m -XX:SurvivorRati…

2. RabbitMQ 服务器 之下载安装

RabbitMQ服务器如何安装&#xff1f; RabbitMQ是一个AMQP&#xff08;Advanced Message Queue&#xff0c;即高级消息队列协议&#xff09;服务器 。 下载地址&#xff1a; RabbitMQ下载 安装说明&#xff1a;各平台下RabbitMQ安装指南 1 Windows 下安装RabbitMQ 1.1 点击 Rabb…