专题:一个自制代码生成器(嵌入式脚本语言)之对象模型

初级代码游戏的专栏介绍与文章目录-CSDN博客

我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。

这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。


专题:一个自制代码生成器(嵌入式脚本语言)之总述-CSDN博客

专题:一个自制代码生成器(嵌入式脚本语言)之对象模型-CSDN博客 (本篇)

专题:一个自制代码生成器(嵌入式脚本语言)之堆栈结构和总入口-CSDN博客

专题:一个自制代码生成器(嵌入式脚本语言)之核心逻辑-CSDN博客

专题:一个自制代码生成器(嵌入式脚本语言)之辅助逻辑-CSDN博客

专题:一个自制代码生成器(嵌入式脚本语言)之应用实例-CSDN博客


目录

一、对象模型概述

二、主要代码

2.1 成员变量定义

2.2 读取和设置

2.3 查找对象

2.4 显示对象

三、堆栈结构和总入口


一、对象模型概述

        表达对象的东西其实都差不多,只是因为都要在里面加自己的特殊东西,所以没有标准。

        所有对象模型都是“节点-节点类型-根据类型不同使用不同的属性和方法-包含的子节点”这么几个要素,这里的对象模型的节点有四种类型:

  • 对象 包含一组通过名称区分的子对象(有点怪吗?可是已经是这样了啊)
  • 指针 指向一个对象
  • 属性 一个值
  • 数组 一个对象数组

        由于设计原因,一个对象的属性通过子对象来实现,直觉上比把属性直接实现为map<属性名,属性值>要复杂些,不过因为程序里面其实都是通过方法来使用的,内部复杂性并没有很大影响。

二、主要代码

2.1 成员变量定义

struct CCTObject
{enum TYPE { OBJECT, POINTER, PROPERTY, ARRAY };TYPE m_type;//根据type决定哪个成员有效CCTObject* m_Pointer;//指针string m_Property;//属性(值)map<string, CCTObject > m_Object;//对象vector<CCTObject >  m_Array;//数组CCTObject() :m_type(OBJECT), m_Pointer(NULL) {}......
}

        通过m_type使用另外四个成员之一。如果要省内存可以用union。

        使用时使用各种专门的读取和设置方法,这些成员原则上是不对外的,其实可以设置成private。

2.2 读取和设置

	string GetDefaultValue(){if (PROPERTY == m_type){return m_Property;}else if (OBJECT == m_type){return m_Object["name"].GetDefaultValue();}else if (POINTER == m_type){return m_Pointer->GetDefaultValue();}else if (ARRAY == m_type){return "ARRAY";}else{return "unknown type";}}string SetDefaultValue(char const* value){if (PROPERTY == m_type){return m_Property = value;}else if (OBJECT == m_type){SetObjectAddProperty("name", value);return value;}else if (POINTER == m_type){return m_Pointer->SetDefaultValue(value);}else if (ARRAY == m_type){return "ARRAY";}else{return "unknown type";}}void SetObjectAddProperty(string name, long value){char buf[64];sprintf(buf, "%ld", value);SetObjectAddProperty(name, buf);}void SetObjectAddProperty(string name, string value){CCTObject p;p.m_type = PROPERTY;p.m_Property = value;m_Object[name] = p;}void SetProperty(string value){m_type = PROPERTY;m_Property = value;}void SetProperty(int value){m_type = PROPERTY;char buf[256];sprintf(buf, "%d", value);m_Property = buf;}void SetPointer(CCTObject* value){m_type = POINTER;m_Pointer = value;}void SetArrayPushBack(CCTObject value){m_type = ARRAY;m_Array.push_back(value);}//给对象初始化一个拥有的数组void SetObjectArrayInit(string name){m_type = OBJECT;CCTObject tmp;tmp.m_type = ARRAY;m_Object[name] = tmp;}//给对象拥有的对象数组添加对象void SetObjectArrayPushBack(string name, CCTObject value){m_type = OBJECT;m_Object[name].SetArrayPushBack(value);}//给对象拥有的属性数组添加属性void SetObjectArrayPushBack(string name, string value){m_type = OBJECT;CCTObject tmp;tmp.SetProperty(value);m_Object[name].SetArrayPushBack(tmp);}void SetObjectAdd(string const& name, CCTObject const& value){m_type = OBJECT;m_Object[name] = value;}void SetObjectAddRef(string const& name, CCTObject * value){m_type = OBJECT;CCTObject tmp;tmp.SetPointer(value);m_Object[name] = tmp;}

        每个方法都很简单。

2.3 查找对象

        这是个很重要的方法,对象名是个点分字符串,也可以包含数组下标操作[]。将对象名拆解后逐级搜索对象。

	//查找对象CCTObject* FindObject(string const& objname){string str;long index = -1;StringTokenizer st(objname, ".");CCTObject* ret = this;DEBUG_LOG << objname << " st.size " << st.size() << endi;for (size_t i = 0; i < st.size(); ++i){DEBUG_LOG << st[i] << endi;while (POINTER == ret->m_type)ret = ret->m_Pointer;size_t pos = st[i].find("[");if (pos != string::npos){index = atol(st[i].substr(pos + 1).c_str());str = st[i].substr(0, pos);}else{index = -1;str = st[i];}if (PROPERTY == ret->m_type){thelog << str << " 不是对象" << ende;return NULL;}else if (OBJECT == ret->m_type){if (ret->m_Object.find(str) != ret->m_Object.end()){ret = &ret->m_Object.find(str)->second;if (index >= 0){if (ARRAY != ret->m_type){thelog << str << " 不是数组" << ende;return NULL;}ret = &ret->m_Array[index];}}else{DEBUG_LOG << str << " 不存在 " << objname << ende;return NULL;}}else{thelog << str << " 未知的类型 " << ret->m_type << ende;return NULL;}}return ret;}

2.4 显示对象

        如何把程序里的数据正确地打印出来对很多程序员好像是个难题啊(更愿意解释为“懒惰”?)。

        输出多级结构的关键是使用正确的缩进,另外要学会如果设置终端的宽度(不然不够显示)。

        使用正确缩进的技巧不过是在递归显示函数里传递深度并用深度构造缩进前缀而已。

	//deep=-1不限深度,自身deep=0string tostring(string& ret, long level, long deep)const{string px;long n;for (long i = 0; i < level; ++i)px += "\t";stringstream ss;if (!(deep < 0 || level < deep)){return "";}if (POINTER == m_type){ss << px << "---->>>> :" << endl;string str;ss << tostring(str, level + 2, deep);}else if (PROPERTY == m_type){ss << px << "PROPERTY " << m_Property << endl;}else if (ARRAY == m_type){ss << px << "ARRAY size " << m_Array.size() << endl;n = 1;for (vector<CCTObject >::const_iterator it = m_Array.begin(); it != m_Array.end(); ++it){ss << px << "\t" << n << endl;string str;ss << it->tostring(str, level + 2, deep);++n;}}else if (OBJECT == m_type){if (0 == m_Object.size()){ss << px << "empty" << endl;}for (long i = 0; i < 3; ++i){n = 1;for (map<string, CCTObject >::const_iterator it = m_Object.begin(); it != m_Object.end(); ++it){if (0 == i && PROPERTY != it->second.m_type)continue;if (1 == i && ARRAY != it->second.m_type)continue;if (2 == i && OBJECT != it->second.m_type)continue;string str;if (PROPERTY != it->second.m_type){ss << px << n << "\t" << it->first << endl;ss << it->second.tostring(str, level + 2, deep);}else{ss << px << n << "\t" << it->first << " \t PROPERTY \t" << it->second.m_Property << endl;}++n;}}}else{ss << px << "此类型不能输出 " << m_type << endl;}return ss.str();}string& toString(string& ret)const{return ret = tostring(ret, 0, -1);}

三、堆栈结构和总入口

        待续


(这里是结束但不是整个系列的结束)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/778057.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Python进行双色球选号

在这篇博客中&#xff0c;我们将介绍如何使用Python编写一个双色球选号的小程序。双色球是一种流行的彩票游戏&#xff0c;选号由6个红球号码和1个蓝球号码组成&#xff0c;红球号码范围是1到33&#xff0c;蓝球号码范围是1到16。 程序设计思路 我们的程序将使用Python的rand…

Windows系统搭建Oracle结合内网穿透实现公网访问本地数据库

文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址4.1 保留一个固定的公网TCP端口地址4.2 配置固定公网TCP端口地址4.3 测试使用固定TCP端口地址远程Oracle 前言 Oracle&#xff0c;是甲骨文公司的一款关系…

3.28 c++

算数运算符 #include <iostream> using namespace std; class Num {int rel; //实部int vir; //虚部 public:Num():rel(2),vir(1){}Num(int rel,int vir):rel(rel),vir(vir){}Num &operator(const Num &other){cout << "Num的拷贝赋值函数"…

Linux(CentOS)/Windows-C++ 云备份项目(结项,项目总结)

项目名称&#xff1a;云备份系统 项目功能&#xff1a; 搭建云备份服务器和客户端。 客户端程序运行在Windows下&#xff0c;将指定的目录下的文件备份到服务器上&#xff0c;并且支持浏览器下载&#xff0c;查看。 其中下载支持断点续传&#xff0c;服务器对备份文件进行热…

java ssh 电影院购票管理系统eclipse开发mysql数据库MVC模式java编程网页设计

一、源码特点 JSP ssh 电影院购票管理系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用 B/S模式开发。开发环境为TOMCAT…

C# 高级文件操作与异步编程探索(初步)

文章目录 文本文件的读写探秘StreamReader 类深度剖析StreamWriter 类细节解读编码和中文乱码的解决方案 二进制文件的读写BinaryReader 类全面解析BinaryWriter 类深度探讨 异步编程与C#的未来方向同步与异步&#xff1a;本质解读Task 的神奇所在async/await 的魔法 在现代编程…

推动制药行业数字化转型:基于超融合架构的MES一体机解决方案

随着中国对信息化重视程度的不断加深&#xff0c;制药行业作为国民经济的重要支柱之一&#xff0c;也在积极寻求通过数字化手段提升产业效率与产品质量。自党的十六大提出“以信息化带动工业化”的战略以来&#xff0c;制药业的这一转型探索尤为迫切。 在现代制药生产中&#…

【已修复】iPhone13 Pro 长焦相机水印(黑斑)修复 洗水印

iPhone13 Pro 长焦相机水印&#xff08;黑斑&#xff09;修复 洗水印 问题描述 iPhone13 Pro 后摄3倍相机有黑色斑点&#xff08;水印&#xff09;&#xff0c;如图所示&#xff0c; 后摄相机布局如图所示&#xff0c; 修复过程 拆机过程有风险&#xff0c;没有把握最好不要…

芒果YOLOv8改进145:全新风格原创YOLOv8网络结构解析图

&#x1f4a1;本篇分享一下个人绘制的原创全新风格 YOLOv8网络结构图 感觉搭配还行&#xff0c;看着比较直观。 该专栏完整目录链接&#xff1a; 芒果YOLOv8深度改进教程 订阅了专栏的读者 可以获取一份 <可以自行修改 / 编辑> 的 YOLOv8结构图修改源文件 YOLOv8结构图…

深入解析Oracle数据库中的分页查询原理及应用实战案例

在Oracle数据库中执行分页查询&#xff0c;尤其是大规模数据检索时&#xff0c;需要高效且精确地定位所需数据范围。 1. 使用 ROWNUM 分页查询 原理&#xff1a; ROWNUM是一个Oracle内建的伪列&#xff0c;它会为每个查询返回的行分配一个从1开始的连续行号。然而&#xff0c…

HackTheBox-Machines--Legacy

文章目录 1 端口扫描2 测试思路3 445端口漏洞测试4 flag Legacy 测试过程 1 端口扫描 nmap -sC -sV 10.129.227.1812 测试思路 目标开启了135、139、445端口&#xff0c;445 SMB服务存在很多可利用漏洞&#xff0c;所以测试点先从445端口开始。而且在Nmap扫描结果中&#xff0c…

项目四-图书管理系统

1.创建项目 流程与之前的项目一致&#xff0c;不再进行赘述。 2.需求定义 需求: 1. 登录: ⽤⼾输⼊账号,密码完成登录功能 2. 列表展⽰: 展⽰图书 3.前端界面测试 无法启动&#xff01;&#xff01;&#xff01;--->记得加入mysql相关操作记得在yml进行配置 配置后启动…

量化交易入门(二十五)什么是RSI,原理和炒股实操

前面我们了解了KDJ&#xff0c;MACD&#xff0c;MTM三个技术指标&#xff0c;也进行了回测&#xff0c;结果有好有坏&#xff0c;今天我们来学习第四个指标RSI。RSI指标全称是相对强弱指标(Relative Strength Index),是通过比较一段时期内的平均收盘涨数和平均收盘跌数来分析市…

03-Pandas的方法介绍

str.startwith()&#xff0c;用于检查列中的值是否以指定的字符串开头 df patients[patients[conditions].str.startswith("DIAB1") | patients["conditions"].str.contains(" DIAB1", regexFalse)]regexFalse代表不使用正则表达式进行匹配&…

3.28总结

1.java学习记录 1.方法的重载 重载换而言之其实就是函数名不变&#xff0c;但是其中的参数需要改变&#xff0c;可以三个方面改变&#xff08;参数类型&#xff0c;参数顺序&#xff0c;参数个数这三个方面入手&#xff0c;这样可以运用的&#xff09; 但是&#xff1a;注意…

2024.3.21|华北水利水电大学江淮校区ACM社团训练赛

2024.3.21|华北水利水电大学江淮校区ACM社团训练赛 1.数字拆解 2.矩阵修改 3.因子数 4.回文数 5.中位数 心有猛虎&#xff0c;细嗅蔷薇。你好朋友&#xff0c;这里是锅巴的C\C学习笔记&#xff0c;常言道&#xff0c;不积跬步无以至千里&#xff0c;希望有朝一日我们积累的滴…

通俗易懂:如何通过JVM参数来调整内存大小?

调整Java虚拟机&#xff08;JVM&#xff09;的内存大小主要是为了优化应用程序性能&#xff0c;防止内存不足而导致的OutOfMemoryError异常。以下是一些关键的JVM参数用于调整内存大小&#xff1a; 1. 堆内存&#xff08;Heap Memory&#xff09; - -Xms&#xff1a;设置JVM的初…

【联邦学习】kubefate安装(docker-compose版)

概念介绍 联邦学习&#xff1a;&#xff08;待补充&#xff09; fate介绍&#xff1a;&#xff08;待补充&#xff09; kubefate介绍&#xff1a;分布式版fate 官网&#xff1a;https://fate.fedai.org/ github&#xff1a;https://github.com/FederatedAI/ 安装 背景 本文…

springboot+vue在idea上面的使用小结

1.在mac上面删除java的jdk方法&#xff1a; sudo rm -rfjdk的路径 sudo rm -rf /Users/like/Library/Java/JavaVirtualMachines/corretto-17.0.10/Contents/Home 2.查询 Mac的jdk版本和路径&#xff1a; /usr/libexec/java_home -V 3.mac上面查询和关闭idea的网页端口&…

快速上手Spring Cloud五:Spring Cloud与持续集成/持续部署(CI/CD)

快速上手Spring Cloud 一&#xff1a;Spring Cloud 简介 快速上手Spring Cloud 二&#xff1a;核心组件解析 快速上手Spring Cloud 三&#xff1a;API网关深入探索与实战应用 快速上手Spring Cloud 四&#xff1a;微服务治理与安全 快速上手Spring Cloud 五&#xff1a;Spring …