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

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

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

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


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

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

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

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

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

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


目录

一、数据库模型

二、应用实例

2.1 创建模型

2.2 生成代码

2.3 生成的代码

三、如何创建模型


一、数据库模型

        数据库模型是根据数据库定义生成数据库操作相关代码的模型,生成的代码是静态代码,具有静态代码的编译时检查和运行效率。

        数据库模型支持表定义、主键、定制的DML操作。对于C++客户代码,所有操作都是基于函数的,函数名和参数清晰地表达了函数的功能。

        下面我们先了解一个应用实例,然后再研究如何编写模型。

二、应用实例

2.1 创建模型

bool Rooster_AddAllTable(CCTModel_UniversalDB* pCTM)
{
	CCTModel_UniversalDB::table* p;

	//资源类型,预定义的数值
	p = pCTM->AddNewTable("RESOURCE_TYPE_D", "资源类型");
	if (NULL == p)return false;
	p->AddMember("RESOURCE_TYPE_ID", "long", "资源类型");
	p->AddMember("COMMENT", "string", "备注");
	p->SetPK("RESOURCE_TYPE_ID");
	p->AddDML("InsertNewResourceType", "insert", "RESOURCE_TYPE_ID,COMMENT", "", "插入新资源类型");

	//资源使用类型,预定义的数值
	p = pCTM->AddNewTable("RESOURCE_USE_TYPE_D", "资源使用类型");
	if (NULL == p)return false;
	p->AddMember("RESOURCE_USE_TYPE_ID", "long", "资源使用类型ID");
	p->AddMember("COMMENT", "string", "备注");
	p->SetPK("RESOURCE_USE_TYPE_ID");
	p->AddDML("InsertNewResourceUseType", "insert", "RESOURCE_USE_TYPE_ID,COMMENT", "", "插入新资源使用类型");

	//资源
	p = pCTM->AddNewTable("RESOURCE_D", "资源");
	if (NULL == p)return false;
	p->AddMember("RESOURCE_ID", "long", "资源ID");
	p->AddMember("RESOURCE_NAME", "string", "资源名称");
	p->AddMember("RESOURCE_TYPE_ID", "long", "资源类型");
	p->AddMember("RESOURCE_WITH_SYS", "long", "资源是否区分sys/sys2");
	p->AddMember("COMMENT", "string", "备注");
	p->SetPK("RESOURCE_ID");
	p->AddDML("InsertNewResource", "insert", "*", "", "插入新资源");
	p->AddDML("GetAllResource", "select", "*", "", "获得全部");

	//任务定义
	p = pCTM->AddNewTable("TASK_D", "任务");
	if (NULL == p)return false;
	p->AddMember("TASK_ID", "long", "任务ID");
	p->AddMember("TASK_NAME", "string", "任务名称");
	p->AddMember("TASK_MULTIPLE", "long", "0非多开1多开");
	p->AddMember("TASK_WITH_SYS", "long", "是否区分sys/sys2");
	p->AddMember("TASK_PRIORITY", "long", "优先级,小的优先");
	p->AddMember("TASK_PLAN_TIME", "string", "执行时间,‘2,8-16’,时间点或时间段");
	p->AddMember("TASK_PLAN_INTERVAL", "long", "执行时间段的执行间隔(分钟0-59)");
	p->AddMember("TASK_START_CMD", "string", "启动命令");
	p->AddMember("COMMENT", "string", "备注");
	p->SetPK("TASK_ID");
	p->AddDML("InsertNewTaskDefine", "insert", "*", "", "插入新任务定义");
	p->AddDML("GetAllTask", "select", "*", "", "获得全部");

	//任务资源使用定义
	p = pCTM->AddNewTable("TASK_RESOURCE_USE_D", "任务资源使用");
	if (NULL == p)return false;
	p->AddMember("TASK_ID", "long", "任务ID");
	p->AddMember("RESOURCE_ID", "long", "资源ID");
	p->AddMember("RESOURCE_USE_TYPE_ID", "long", "资源使用类型ID");
	p->AddMember("COMMENT", "string", "备注");
	p->SetPK("TASK_ID,RESOURCE_ID");
	p->AddDML("InsertNewTaskResurceUseDefine", "insert", "TASK_ID,RESOURCE_ID,RESOURCE_USE_TYPE_ID,COMMENT", "", "插入新任务资源使用定义");
	p->AddDML("GetAllTaskResourceUse", "select", "*", "", "获得全部");

	//任务队列表
	p = pCTM->AddNewTable("TASK_QUEUE", "待执行的任务队列");
	if (NULL == p)return false;
	p->AddMember("TASK_ID", "long", "任务ID");
	p->AddMember("SYS", "long", "维度1");
	p->AddMember("SYS2", "long", "维度2");
	p->AddMember("TASK_NAME", "string", "任务名称(参考)");
	p->AddMember("TASK_PRIORITY", "long", "优先级,小的优先(参考)");
	p->AddMember("COMMENT", "string", "备注(参考)");
	p->AddMember("INSERT_TIME", "time", "开始时间", "", "TIME_LOG");
	p->SetPK("TASK_ID,SYS,SYS2");
	p->AddDML("InsertNewTaskQueue", "insert", "TASK_ID,SYS,SYS2,TASK_NAME,TASK_PRIORITY,COMMENT,INSERT_TIME", "", "插入新任务队列");
	p->AddDML("DeleteTaskQueue", "delete", "", "TASK_ID,SYS,SYS2", "删除任务队列");
	p->AddDML("GetAllTaskQueue", "select", "*", "", "获取全部任务队列");
	p->AddDML("GetTaskQueue", "select", "*", "TASK_ID,SYS,SYS2", "获取任务队列");

	//任务执行表
	p = pCTM->AddNewTable("TASK_LOG", "任务日志");
	if (NULL == p)return false;
	p->AddMember("TASK_LOG_ID", "long", "任务执行序列号SEQ_TASK_LOG");
	p->AddMember("TASK_ID", "long", "任务ID");
	p->AddMember("SYS", "long", "维度1");
	p->AddMember("SYS2", "long", "维度2");
	p->AddMember("PID", "long", "任务所在的进程,客户方写入");
	p->AddMember("START_TIME", "time", "开始时间", "", "TIME_LOG");
	p->AddMember("FINISH_TIME", "time", "结束时间", "", "TIME_LOG");
	p->AddMember("RETURN_VALUE", "long", "返回值 0成功 <0Rooster错误 >0任务错误");
	p->AddMember("UPDATE_TIME", "time", "记录更新时间", "", "TIME_LOG");
	p->SetPK("TASK_LOG_ID");
	p->AddDML("InsertNewTaskLog", "insert", "TASK_LOG_ID,TASK_ID,SYS,SYS2,START_TIME,UPDATE_TIME", "", "插入新任务日志");
	p->AddDML("UpdateTaskLog", "update", "PID,UPDATE_TIME", "TASK_LOG_ID", "更新任务日志", "finish_time=0");
	p->AddDML("FinishTaskLog", "update", "FINISH_TIME,RETURN_VALUE,UPDATE_TIME", "TASK_LOG_ID", "更新任务日志", "finish_time=0");
	p->AddDML("GetCurrentTask", "select", "*", "", "获取正在运行的任务", "finish_time=0");

	//序列
	if (NULL == pCTM->AddNewSequence("SEQ_TASK_LOG", "TASK日志序列", 0))return false;

	return true;
}

        这个代码创建了一组表和一个序列,每一行代码的功能都是显而易见的。

2.2 生成代码

int main(int argc, char** argv)
{
	if (!InitActiveApp("CCTModel_UniversalDB", 1024 * 1024, argc, argv))exit(1);

	if (sizeof(long) != 8)
	{
		thelog << "非64位程序!" << ende;
	}

	G_IS_DEBUG = true;

	CCTModel_UniversalDB ctm;
	if (!Rooster_AddAllTable(&ctm))
	{
		thelog << "执行失败" << ende;
		return __LINE__;
	}
	if (!ctm.CreateCode("ns_rooster_struct", "RoosterStruct", "."))
	{
		thelog << "执行失败" << ende;
		return __LINE__;
	}

	thelog << "程序退出" << endi;
	return 0;
}

        有用的就两句:Rooster_AddAllTable创建模型,CreateCode生成代码。

2.3 生成的代码

        生成的一组文件:

        总入口头文件是_cc_CRoosterStruct.h:

//_cc_CRoosterStruct.h 自动生成的代码
//
// Copyright (c) ct  All rights reserved.
// 版权所有 ct 保留所有权利
//

//警告:本文件由CT系统自动生成,不可手工修改

#ifndef CTFC_RoosterStruct_H
#define CTFC_RoosterStruct_H 1

//如果需要使用内存数据库直连功能,请在包含本头文件之前定义 CTFC_RoosterStruct_H_SHM_DB
//如果需要使用MariaDB功能,请在包含本头文件之前定义 CTFC_RoosterStruct_H_MARIA_DB
#include "_cc_RoosterStruct_RESOURCE_TYPE_D.h"
#include "_cc_RoosterStruct_RESOURCE_USE_TYPE_D.h"
#include "_cc_RoosterStruct_RESOURCE_D.h"
#include "_cc_RoosterStruct_TASK_D.h"
#include "_cc_RoosterStruct_TASK_RESOURCE_USE_D.h"
#include "_cc_RoosterStruct_TASK_QUEUE.h"
#include "_cc_RoosterStruct_TASK_LOG.h"
#include "_cc_RoosterStruct_SEQ_TASK_LOG.h"

using namespace ns_my_std;

namespace ns_rooster_struct
{
	class CShmDB_RoosterStruct
	{
	public:
		//表
		CRoosterStruct_RESOURCE_TYPE_D m_RESOURCE_TYPE_D;//资源类型
		CRoosterStruct_RESOURCE_USE_TYPE_D m_RESOURCE_USE_TYPE_D;//资源使用类型
		CRoosterStruct_RESOURCE_D m_RESOURCE_D;//资源
		CRoosterStruct_TASK_D m_TASK_D;//任务
		CRoosterStruct_TASK_RESOURCE_USE_D m_TASK_RESOURCE_USE_D;//任务资源使用
		CRoosterStruct_TASK_QUEUE m_TASK_QUEUE;//待执行的任务队列
		CRoosterStruct_TASK_LOG m_TASK_LOG;//任务日志

		//序列
		CRoosterStruct_SEQ_TASK_LOG m_SEQ_TASK_LOG;//TASK日志序列
	public:
#ifdef CTFC_RoosterStruct_H_SHM_DB
#define CTFC_RoosterStruct_H_WITH_DB
		typedef CShmDB T_DB;
#endif

#ifdef CTFC_RoosterStruct_H_MARIA_DB
#define CTFC_RoosterStruct_H_WITH_DB
		typedef CMariaDB T_DB;
#endif
	private:
#ifdef CTFC_RoosterStruct_H_WITH_DB
		T_DB m_ShmDB;
		T_DB * pDB;
#endif
	public:
#ifdef CTFC_RoosterStruct_H_WITH_DB
		//返回内部数据库对象
		T_DB * getDB(){return pDB;}
		//直连初始化
		bool DBInit(char const * db = nullptr)
		{
#ifdef CTFC_RoosterStruct_H_SHM_DB
			CShmActiveObjects * p;
			p = m_ShmDB.GetCShmActiveObjects();
			if (!p->isConnected() && !p->Attach(false))
#endif
#ifdef CTFC_RoosterStruct_H_MARIA_DB
			if(!m_ShmDB.Connect(db))
#endif
			{
				thelog << "CRoosterStruct连接失败" << ende;
				return false;
			}
			DEBUG_LOG << "CRoosterStruct连接成功" << endi;

			pDB = &m_ShmDB;
			
			m_RESOURCE_TYPE_D.Init(pDB);
			m_RESOURCE_USE_TYPE_D.Init(pDB);
			m_RESOURCE_D.Init(pDB);
			m_TASK_D.Init(pDB);
			m_TASK_RESOURCE_USE_D.Init(pDB);
			m_TASK_QUEUE.Init(pDB);
			m_TASK_LOG.Init(pDB);

			m_SEQ_TASK_LOG.Init(pDB);

			return true;
		}
		//直连断开
		bool DBUnInit()
		{
#ifdef CTFC_RoosterStruct_H_SHM_DB
			CShmActiveObjects * p;
			p = m_ShmDB.GetCShmActiveObjects();
			if (p->isConnected())p->Detach();
#endif
#ifdef CTFC_RoosterStruct_H_MARIA_DB
			pDB->Close();
#endif
			pDB = NULL;
			return true;
		}
		//直连创建所有数据库对象
		bool DBCreateAllDBObject()
		{
			//创建表
			if(!m_RESOURCE_TYPE_D.CreateTable())return false;
			if(!m_RESOURCE_USE_TYPE_D.CreateTable())return false;
			if(!m_RESOURCE_D.CreateTable())return false;
			if(!m_TASK_D.CreateTable())return false;
			if(!m_TASK_RESOURCE_USE_D.CreateTable())return false;
			if(!m_TASK_QUEUE.CreateTable())return false;
			if(!m_TASK_LOG.CreateTable())return false;

			//创建序列
			if(!m_SEQ_TASK_LOG.CreateSequence())return false;

			return true;
		}
		//直连显示所有数据库对象
		bool DBShowAllDBObject()
		{
			//显示表
			if(!m_RESOURCE_TYPE_D.Show())return false;
			if(!m_RESOURCE_USE_TYPE_D.Show())return false;
			if(!m_RESOURCE_D.Show())return false;
			if(!m_TASK_D.Show())return false;
			if(!m_TASK_RESOURCE_USE_D.Show())return false;
			if(!m_TASK_QUEUE.Show())return false;
			if(!m_TASK_LOG.Show())return false;

			//显示序列
			thelog << "sequence:" << endl << "-------------------------" << endl;
			theLog<< "SEQ_TASK_LOG " << m_SEQ_TASK_LOG.GetSequenceValue() << endl;
			theLog << "-------------------------" << endi;

			return true;
		}
#endif
	};
}
#endif

        这个文件看起来和普通手写的文件没有任何区别,除了它真的是用代码模板生成的。

        再来看看生成这个文件的模板_t_UniversalDB.h.ct是什么样的:

//_cc_C${SYS}.h 自动生成的代码
//
// Copyright (c) ct  All rights reserved.
// 版权所有 ct 保留所有权利
//

//警告:本文件由CT系统自动生成,不可手工修改

#ifndef CTFC_${SYS}_H
#define CTFC_${SYS}_H 1

//如果需要使用内存数据库直连功能,请在包含本头文件之前定义 CTFC_${SYS}_H_SHM_DB
//如果需要使用MariaDB功能,请在包含本头文件之前定义 CTFC_${SYS}_H_MARIA_DB
<%foreach table in ${tables}%>
#include "_cc_${SYS}_${table}.h"
<%endforeach%>
<%foreach sequence in sequences%>
#include "_cc_${SYS}_${sequence}.h"
<%endforeach%>

using namespace ns_my_std;

namespace ${NAMESPACE}
{
	class CShmDB_${SYS}
	{
	public:
		//表
		<%foreach table in tables%>
		C${SYS}_${table} m_${table};//${table.comment}
		<%endforeach%>

		//序列
		<%foreach sequence in sequences%>
		C${SYS}_${sequence} m_${sequence};//${sequence.comment}
		<%endforeach%>
	public:
#ifdef CTFC_${SYS}_H_SHM_DB
#define CTFC_${SYS}_H_WITH_DB
		typedef CShmDB T_DB;
#endif

#ifdef CTFC_${SYS}_H_MARIA_DB
#define CTFC_${SYS}_H_WITH_DB
		typedef CMariaDB T_DB;
#endif
	private:
#ifdef CTFC_${SYS}_H_WITH_DB
		T_DB m_ShmDB;
		T_DB * pDB;
#endif
	public:
#ifdef CTFC_${SYS}_H_WITH_DB
		//返回内部数据库对象
		T_DB * getDB(){return pDB;}
		//直连初始化
		bool DBInit(char const * db = nullptr)
		{
#ifdef CTFC_${SYS}_H_SHM_DB
			CShmActiveObjects * p;
			p = m_ShmDB.GetCShmActiveObjects();
			if (!p->isConnected() && !p->Attach(false))
#endif
#ifdef CTFC_${SYS}_H_MARIA_DB
			if(!m_ShmDB.Connect(db))
#endif
			{
				thelog << "C${SYS}连接失败" << ende;
				return false;
			}
			DEBUG_LOG << "C${SYS}连接成功" << endi;

			pDB = &m_ShmDB;
			
			<%foreach table in tables%>
			m_${table}.Init(pDB);
			<%endforeach%>

			<%foreach sequence in sequences%>
			m_${sequence}.Init(pDB);
			<%endforeach%>

			return true;
		}
		//直连断开
		bool DBUnInit()
		{
#ifdef CTFC_${SYS}_H_SHM_DB
			CShmActiveObjects * p;
			p = m_ShmDB.GetCShmActiveObjects();
			if (p->isConnected())p->Detach();
#endif
#ifdef CTFC_${SYS}_H_MARIA_DB
			pDB->Close();
#endif
			pDB = NULL;
			return true;
		}
		//直连创建所有数据库对象
		bool DBCreateAllDBObject()
		{
			//创建表
			<%foreach table in tables%>
			if(!m_${table}.CreateTable())return false;
			<%endforeach%>

			//创建序列
			<%foreach sequence in sequences%>
			if(!m_${sequence}.CreateSequence())return false;
			<%endforeach%>

			return true;
		}
		//直连显示所有数据库对象
		bool DBShowAllDBObject()
		{
			//显示表
			<%foreach table in tables%>
			if(!m_${table}.Show())return false;
			<%endforeach%>

			//显示序列
			thelog << "sequence:" << endl << "-------------------------" << endl;
			<%foreach sequence in sequences%>
			theLog<< "${sequence} " << m_${sequence}.GetSequenceValue() << endl;
			<%endforeach%>
			theLog << "-------------------------" << endi;

			return true;
		}
#endif
	};
}
#endif

        这就是一个代码模板编写的典型例子,用到了大量的循环处理和变量替换。看起来像asp?嗯,就是模仿asp啊。

三、如何创建模型

        下一篇将详细解释这个模型(原则上,除了最终生成的的是这个脚本生成器要求的对象结构外模型和脚本生成器并没有更多关联)。


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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络原理-传输层-UDP报文结构

本文介绍UDP报文 有很多友友搞不清楚UDP报文的详细结构还有TCP的详细结构,所以专门分开来讲 以免弄混. 首先我们先看一下整个UDP结构,让大家有一个全方面的认识 下面我们来详细解释UDP报 16位源端口号(本机):就是2字节大小,16个二进制位. 16位目的端口号(目的机):也是2字节…

element-ui autocomplete 组件源码分享

紧接着 input 组件的源码&#xff0c;分享带输入建议的 autocomplete 组件&#xff0c;在 element-ui 官方文档上&#xff0c;没有这个组件的 api 目录&#xff0c;它的 api 是和 input 组件的 api 在一起的&#xff0c;看完源码之后发现&#xff0c;源码当中 autocomplete 组件…

MTK8781安卓核心板_MT8781(Helio G99)核心板性能参数

MT8781安卓核心板搭载了八核CPU&#xff0c;其中包括两个主频高达2.2GHz的高性能Arm Cortex-A76处理器。这一处理器采用了台积电6纳米级芯片生产工艺&#xff0c;以及先进的3D图形功能的高性能Arm Mali G57级GPU。通过超快LPDDR4X内存和UFS 2.2存储供电&#xff0c;不仅提高了游…

新版Idea2023.3.5与lombok冲突、@Data失效

新版idea和lombok冲突&#xff0c;加上Data&#xff0c;其他地方get set也不报错&#xff0c;但是一运行就找不到get set方法。 但是直接使用Getter和Setter可以访问、应该是Data失效了。 解决方法&#xff1a; 看推上介绍是 lombok 与 idea 采集 get 、set 方法的时候所用的技…

成都市酷客焕学新媒体科技有限公司:实现品牌的更大价值!

成都市酷客焕学新媒体科技有限公司专注于短视频营销&#xff0c;深知短视频在社交媒体中的巨大影响力。该公司巧妙地将品牌信息融入富有创意和趣味性的内容中&#xff0c;使观众在轻松愉悦的氛围中接受并传播这些信息。凭借独特的创意和精准的营销策略&#xff0c;成都市酷客焕…

llama-index 结合chatglm3-6B 利用RAG 基于文档智能问答

简介 llamaindex结合chatglm3使用 import os import torch from llama_index.core import VectorStoreIndex, ServiceContext from llama_index.core.callbacks import CallbackManager from llama_index.core.llms.callbacks import llm_completion_callback from llama_ind…

计算机网络链路层

数据链路 链路是从一个节点到相邻节点之间的物理线路&#xff08;有线或无线&#xff09; 数据链路是指把实现协议的软件和硬件加到对应链路上。帧是点对点信道的数据链路层的协议数据单元。 点对点信道 通信的主要步骤&#xff1a; 节点a的数据链路层将网络层交下来的包添…

【three.js】后期处理outlinePass描边实现点击选中物体效果

在 Three.js 中&#xff0c;通过后期处理技术可以实现各种视觉效果&#xff0c;其中包括描边&#xff08;Outline&#xff09;效果&#xff0c;用于突出显示或选中特定物体。本文将重点介绍如何使用 Three.js 中的 OutlinePass 后期处理效果来实现点击选中物体的效果&#xff0…

LeetCode:509斐波那契数 C语言

斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;其中 n > 1给定 n &a…

【笔记】RDD算子操作(Spark基础知识)

持续更新中&#xff01;&#xff01;&#xff01; 目录 一、RDD的创建 1.从本地创建 &#xff08;1&#xff09;本地文件 &#xff08;2&#xff09;hdfs文件&#xff08;先提前创建目录并上传文件&#xff09; 2.从集合创建&#xff08;通过并行集合&#xff08;列表&am…

【C语言基础】:数据在内存中的存储

文章目录 一、整数在内存中的存储二、大小端字节序和字节序判断1. 为什么有大小端&#xff1f;2. 练习 三、浮点数在内存中的存储1. 浮点数的存储1.1 浮点数的存储过程1.2 浮点数取的过程 四、题目解析 书山有路勤为径&#xff0c;学海无涯苦作舟。 创作不易&#xff0c;宝子们…

基于springboot+vue+Mysql的财务管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

LabVIEW单片机的废气再循环EGR检测系统

LabVIEW单片机的废气再循环EGR检测系统 实现了一种基于LabVIEW和STM32F103VET6单片机的EGR&#xff08;废气再循环&#xff09;检测系统&#xff0c;监测和控制船用二冲程柴油机的EGR运行状态。通过替代传统的NI采集卡&#xff0c;系统不仅降低了成本&#xff0c;同时也提升了数…

es6 Class基本语法和继承

es6 Class基本语法 class的基本语法&#xff1a; ES6 的class只是一个语法糖&#xff0c;它的绝大部分功能&#xff0c;ES5 都可以做到&#xff0c;新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已 传统用构造函数生成实例 function Point(x, y) {th…

Unity AI Navigation自动寻路

目录 前言一、Unity中AI Navigation是什么&#xff1f;二、使用步骤1.安装AI Navigation2.创建模型和材质3.编写向目标移动的脚本4.NavMeshLink桥接组件5.NavMeshObstacle组件6.NavMeshModifler组件 三、效果总结 前言 Unity是一款强大的游戏开发引擎&#xff0c;而人工智能&a…

【漏洞复现】chatgpt pictureproxy.php SSRF漏洞(CVE-2024-27564)

0x01 漏洞概述 ChatGPT pictureproxy.php接口存在服务器端请求伪造 漏洞&#xff08;SSRF&#xff09; &#xff0c;未授权的攻击者可以通过将构建的 URL 注入 url参数来强制应用程序发出任意请求。 0x02 测绘语句 fofa: icon_hash"-1999760920" 0x03 漏洞复现 G…

Machine Learning机器学习之统计分析

目录 前言 机器学习之统计分析 统计学的主要目标包括&#xff1a; 统计学核心概念&#xff1a; 统计基础&#xff1a; 训练误差&#xff1a; 常见的损失函数&#xff1a; 正则化和交叉验证 博主介绍&#xff1a;✌专注于前后端、机器学习、人工智能应用领域开发的优质创作者、秉…

使用pytorch构建一个初级的无监督的GAN网络模型

在这个系列中将系统的构建GAN及其相关的一些变种模型&#xff0c;来了解GAN的基本原理。本片为此系列的第一篇&#xff0c;实现起来很简单&#xff0c;所以不要期待有很好的效果出来。 第一篇我们搭建一个无监督的可以生成数字 (0-9) 手写图像的 GAN&#xff0c;使用MINIST数据…

进阶了解C++(6)——二叉树OJ题

Leetcode.606.根据二叉树创建字符串&#xff1a; 606. 根据二叉树创建字符串 - 力扣&#xff08;LeetCode&#xff09; 难度不大&#xff0c;根据题目的描述&#xff0c;首先对二叉树进行一次前序遍历&#xff0c;即&#xff1a; class Solution { public:string tree2str(Tr…

TheMoon 恶意软件短时间感染 6,000 台华硕路由器以获取代理服务

文章目录 针对华硕路由器Faceless代理服务预防措施 一种名为"TheMoon"的新变种恶意软件僵尸网络已经被发现正在侵入全球88个国家数千台过时的小型办公室与家庭办公室(SOHO)路由器以及物联网设备。 "TheMoon"与“Faceless”代理服务有关联&#xff0c;该服务…
最新文章