焦头烂额的考试月终于过去了,终于有时间能停下来思考记录一下这一个月学过的东西,首先先总结一下,在自己仿写魂斗罗游戏时遇见的问题之一,人物在移动的时候如何去判断什么时候掉入水中显示水中画面,什么时候敌人该开枪,这个时候我使用了一堆数字来描述地图,如图

但是在代码实现时,就得用一大堆判断,来判断何时应该创建对象来调用成员函数,其代码繁杂不说,更加降低了代码的复用性,如果我想在其中添加功能,还得再修改代码,这个时候我就想到了动态创建数组这个东西,根据我输入的数字长度,数组可以自动去增长,那对象是不是可以动态的去创建呢?,可能是我搜索的有问题,在网上很少有介绍这方面的过程,我觉得还是有必要记录一下,给其他人也提供一个借鉴

首先先用字符串去做一个实验,添加三个类,我想通过输入一个字符串就能创建相应的对象,此时就需要一系列判断

     char pStr[] = {};
cin >> pStr;
if(strcmp(pStr,"AAAA") == )
AAAA *p = new AAAA;
if(strcmp(pStr,"BBBB") == )
BBBB *p = new BBBB;
if(strcmp(pStr,"DDDD") == )
DDDD *p = new DDDD;

这个时候就会出现我遇到的情况,代码繁杂,降低复用性,首先修改的就是创建对象,据说好的程序员不会写出来毁灭地球的代码,而是写一个毁灭行星的函数,把地球当作参数传进去

 void CreateObjectAAAA()
{
AAAA *p = new AAAA;
}
void CreateObjectBBBB()
{
BBBB *p = new BBBB;
}
void CreateObjectDDDD()
{
DDDD *p = new DDDD;
}
int main()
{
char pStr[] = {};
cin >> pStr;
if(strcmp(pStr,"AAAA") == )
CreateObjectAAAA();
if(strcmp(pStr,"BBBB") == )
CreateObjectBBBB();
if(strcmp(pStr,"DDDD") == )
CreateObjectDDDD();

然后如何能动态创建呢,可以想到链表可以实现动态的创建,但是创建对象无法用链表来表示,但可以将字符串,创建对象的函数指针打包成一个结点,只要输入字符串,就可以遍历链表实现创建了

 struct Node
{
char pStr[];
void (*pfnCreateObject)();
Node* pNext;
};

但现在问题是如何实现普适性,比如直接在类里贴一个宏,之后不用再创建对象了

首先是统一结点,由于在创建对象之后需要使用对象,创建对象函数return的值也都不一样,这样的话,结点里的函数指针的类型也不一样了,统一结点的方法就是利用父类指针指向子类对象,为这些类创建一个父类,这个函数指针直接定义为父类即可

 struct Node
{
char pStr[];
COObject* (*pfnCreateObject)();
Node* pNext;
};
COObject* CreateObjectAAAA()
{
AAAA *p = new AAAA;
return p;
}
COObject* CreateObjectBBBB()
{
BBBB *p = new BBBB;
return p;
}
COObject* CreateObjectDDDD()
{
DDDD *p = new DDDD;
return p;
}

接下来用宏代替每个类里的什么东西呢,换句话说哪些东西需要写到类内呢?

结构体,遍历匹配,放在父类中

 #pragma once
class COObject;
struct Node
{
char pStr[];
COObject* (*pfnCreateObject)();
Node* pNext;
};
class COObject
{
public:
COObject(void);
virtual ~COObject(void);
public:
COObject *Create(const char *pszClassName);
};
 #include "OObject.h"
#include<string.h> COObject::COObject(void)
{
} COObject::~COObject(void)
{
}
COObject *COObject::Create(const char *pszClassName)
{
Node *pTemp = ;
while(pTemp)
{
if(strcmp(pTemp->pStr,pszClassName) == )
{
return pTemp->pfnCreateObject();
}
pTemp = pTemp->pNext;
}
return ;
}

而每一个子类中则放入创建结点,创建对象函数,其中有一点尤为注意,因为此时并未创建对象,所以这里的成员函数都是静态成员

 #pragma once
#include"OObject.h"
class AAAA : public COObject
{
public:
AAAA(void);
~AAAA(void);
public:
static Node node;
static COObject*CreateObject();
};
 #include "AAAA.h"
Node AAAA::node = {"AAAA",,&AAAA::CreateObject};
COObject*AAAA::CreateObject()
{
return new AAAA;
} AAAA::AAAA(void)
{
} AAAA::~AAAA(void)
{
}

每个类都如此,但是当我实际操作的时候,程序却崩了,调试后发现,在遍历中,我每加一个结点就得修改一此头结点,那我写上面这些的意义就不存在了,都是添加还不如一大堆if看起来逻辑清晰呢,最后通过一个办法可以解决,由于在函数之外不允许调用函数,除了一个,那就是构造函数,我在父类中又定义了一个专门添加的类,在这个类的构造里我把添加的结点传进去,进行头结点的更替,在遍历中始终从头节点开始遍历。那么在以后的编程中,如果我不知道何时该创建对象的话,在类的头文件和实现中就可以分别贴上这两个宏,再继承一个COObject的接口类即可。

#define DECLEAR_DYNCREATE()\ static Node node;\ static COObject*CreateObject();

 #define IMPLEMENT_DYNCREATE(ThisClass)\
Node ThisClass::node = {#ThisClass,,&ThisClass::CreateObject};\
InitObject init##ThisClass(&ThisClass::node);\
COObject* ThisClass::CreateObject()\
{\
return new ThisClass;\
}

2019-06-23 14:17:33 编程小菜鸟自我反思,大家可以留下自己的意见和建议,谢谢!!!

C++语言动态创建对象的更多相关文章

  1. C# 中反射获取某类的子类和根据类型名动态创建对象

    有时候,为了快速批量处理已经实现某个基类或者某个接口的子类,需要通过反射的方式获取到他们的类类型(Type),然后再通过 1 Activator.CreateInstance(objType); 或者 ...

  2. Rmarkdown用法与R语言动态报告

    Rmarkdown用法与R语言动态报告数据分析用R语言非常便捷,因为R语言的社区强大,并且在不断更新和完善,提供了各种分析利器.Knitr和Rmarkdown包则是数据分析中的动态报告利器. 下面是一 ...

  3. swift如何动态创建对象

    前言: 在一些大型的项目中常常在加载页面的时候根据服务器请求下来的数据动态创建视图控制器对象,最近的一个项目就有这一方面的需求,加载页面之前需要先请求服务器的数据得到一个JSON字典,根据里面字符串的 ...

  4. C#主要支持 5 种动态创建对象的方式

    C#主要支持 5 种动态创建对象的方式: 1. Type.InvokeMember 2. ContructorInfo.Invoke 3. Activator.CreateInstance(Type) ...

  5. 于Unity3D动态创建对象和创建Prefab三种方式的原型对象

    于Unity3D动态创建对象和创建Prefab三种方式的原型对象 u3d在动态创建的对象,需要使用prefab 和创建时 MonoBehaviour.Instantiate( GameObject o ...

  6. C# 利用反射动态创建对象——带参数的构造函数和String类型

    C# 利用反射动态创建对象——带参数的构造函数和String类型 最近笔者有一个想法需要利用反射动态创建对象(如string,int,float,bool,以及自定义类等)来实现,一直感觉反射用不好, ...

  7. 使用hql动态创建对象问题

    前段时间由于需求要添加报表数据,调整ireport后,打印pdf文件出现数据错位的情况,调试发现不是ireport问题,就查看了后台传送的数据,最后发现传送的对象属性值已经就是错位的,那就是获取对象时 ...

  8. MFC中关于运行时类信息及动态创建对象的两个宏的意义(转)

    http://blog.csdn.net/ligand/article/details/49839507 MFC运行时类信息 用途: 程序在运行时,获取对象类的信息及类的继承关系 实现: 1.定义的类 ...

  9. C#利用反射动态创建对象 带参数的构造函数和String类型 (转载)

    最近笔者有一个想法需要利用反射动态创建对象(如string,int,float,bool,以及自定义类等)来实现,一直感觉反射用不好,特别是当构造函数带参数的时候.MSDN上给出的例子十分复杂,网上的 ...

随机推荐

  1. #C++初学记录(遍历)

    hide handkerchief Problem Description The Children's Day has passed for some days .Has you remembere ...

  2. NPAPI插件开发详细记录:用VS2010开发NPAPI插件步骤<转>

    原帖地址:https://blog.csdn.net/z6482/article/details/7660748 ------------------------------------------- ...

  3. springboot整合vue实现上传下载文件

    https://blog.csdn.net/yhhyhhyhhyhh/article/details/89888953 文章目录 springboot整合vue实现上传下载文件 1上传下载文件api文 ...

  4. 使用OpenCV(C ++ / Python)进行人脸交换

    -- 图3.面部对齐.左:检测到面部标志和凸包.中:凸包上的点的Delaunay三角剖分.右:通过仿射扭曲三角形进行面部对齐. 1 人脸对齐 1.1 脸部地标检测 两个脸部的几何形状非常不同,因此我们 ...

  5. java泛型--问号?和T或E或K或V的区别

    所谓泛型,就是在定义类.接口.方法.参数或成员变量的时候,指定它们操作对象的类型为通用类型. 使用 尖括号 <> 操作符 (The diamond operator )表示泛型, 尖括号内 ...

  6. Web 性能压力测试工具之 Siege 详解

    Siege是一款开源的压力测试工具,设计用于评估WEB应用在压力下的承受能力.可以根据配置对一个WEB站点进行多用户的并发访问,记录每个用户所有请求过程的相应时间,并在一定数量的并发访问下重复进行.s ...

  7. 先查询再插入,改为存储过程,java部分入参出参、mybatisxml【我】

    先查询再插入,改为存储过程 create or replace procedure PRO_REVENUE_SI(l_p_cd in Varchar2, l_c_cd in Varchar2, l_p ...

  8. 123457123456#0#----com.DoraGame.YingYu65--前拼后广--儿童英语doraX

    com.DoraGame.YingYu65--前拼后广--儿童英语doraX

  9. Error:java: Compilation failed: internal java compiler

    errorInformation:java: javacTask: 源发行版 1.8 需要目标发行版 1.8 解决此类问题 检查自己的JDK是否一致 1  setting--------built  ...

  10. oracle存储过程(带参数的存储过程)

    带参数的存储过程 举例:为指定的员工涨100元的工资,打印涨前和涨后的工资 如果带参,需要指定是输入参数还是输出参数 create or replace procedure raisesalary(e ...