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


     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及其派生类的继承层次和隐藏具体实现
    修改完成后的代码版本
    源码
  • 相关阅读:
    安装PyExecJS出现问题
    常用模块
    python2和python3的区别
    正则表达式
    MySQL之表的关系
    Python与MySQL的交互
    select 查询
    MySQL之表的连接
    bug
    黑盒测试-判定表驱动法
  • 原文地址:https://www.cnblogs.com/neking/p/3128145.html
Copyright © 2020-2023  润新知