表达式计算器类的设计2(表达式计算器5)
计算器的github下载地址:https://github.com/ljian1992/calculator
符号表,函数表,变量存储表
表达式计算器,需要支持变量和函数,而变量和函数都是些符号,因此设置一个SymbolTable类来存储这些符号。符号有两种,一种是变量,一种是函数,故在设置一个Storage类存储变量中的值,设置一个FunctionTable类来存储函数。由于这三中类存在着联系,现在在设置一个Calc类来管理它们。
SymbolTable类,FunctionTable类,Storage类,Calc类的关系
根据符号表中的符号对应的的ID,在Storage中根据ID找到变量的值,或者是在FunctionTable中根据ID找到相对应得数学函数
SymbolTable类,FunctionTable类,Storage类,Calc类的设计
SymbolTable类 class SymbolTable : public Serializable { private: std::map<const std::string, unsigned int> dictionary_; //存储符号与id相对应得关系 unsigned int curId_; //存储将要加入符号表的符号id public: enum { IDNOTFOUND = 0xFFFFFFFF }; //IDNOTFOUND代表在符号表中找不到相应的符号 SymbolTable() : curId_(0) {} unsigned int Add(const std::string& str); //向符号表中加入符号 unsigned int Find(const std::string& str) const; //根据符号寻找符号表中是否存储该符号 unsigned int GetCurId()const; //获取下一个的加入符号表的符号id void Clear(); //清楚符号表 const std::string &GetSymbolName(unsigned int id) const;//根据id查找并获取符号表中的符号 virtual void Serialize(Serializer& out) const; //文件存储 virtual void DeSerialize(DeSerializer& in); //文件加载 }; Storage类 class Storage : public Serializable { private: std::map<unsigned int, double> cells_; //存储符号表中id与值多对应的关系 public: Storage(SymbolTable& tbl); void Clear(); //清除数据 void AddConstants(SymbolTable& tbl); //增加常量,目前只支持pi e double GetValue(unsigned int id) const; //根据id获得想对于的值 unsigned int GetSize() const; //获取map中有多少个数据 void SetValue(unsigned int id, double val); //设置map中的值 void AddValue(unsigned int id, double val); //想map中添加值 virtual void Serialize(Serializer& out) const;//将Storage类中的值存入文件存储 virtual void DeSerialize(DeSerializer& in); //将文件中的值加载到Storage类中 }; FunctionTable类 typedef double(*PtrFun)(double); //重命名了一种函数指针类 class FunctionTable { private: std::map<unsigned int, PtrFun> funsMap_; //存储符号表中的id与对应的数学函数指针 public: FunctionTable(SymbolTable& tbl); void Init(SymbolTable& tbl); //存储是函数表 PtrFun GetFunction(unsigned int id) const; //根据id获取函数表中对应的函数 unsigned int GetSize() const; //获得函数表中有多少个函数 ~FunctionTable(); }; Calc类 class Calc : public Serializable { friend class Parser; //使到Parser类方便的访问Calc的私有成员 private: //由于Storage的构造函数需要用到SymbolTable的引用,故声明顺序SymbolTable在Storage的前面 SymbolTable symTbl_; FunctionTable functionTbl_; //由于函数表中的函数是固定的,因此把函数表的构造放在符号表的前面 Storage storage_; //变量的个数是不固定的 unsigned int FindSymbol(const std::string& str) const; //在符号表中查找str符号 unsigned int AddSymbol(const std::string& str); //往符号表中添加符号 Storage& GetStorage(); //获取stroage_的引用 bool IsFunction(unsigned int id) const; //判断是否是函数 PtrFun GetFunction(unsigned int id) const; //获取函数指针 double GetVariableValue(unsigned int id) const; //获取变量的值 public: Calc() : symTbl_(), functionTbl_(symTbl_), storage_(symTbl_) {} void ListFun() const; //打印函数表 void ListVariable() const; //打印变量表 virtual void Serialize(Serializer& out) const; //将函数表和变量表中的内容存储到文件中 virtual void DeSerialize(DeSerializer& in); //从文件中加载内容到符号表和变量表中 };