C++语言动态创建对象

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

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

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

1     char pStr[20] = {0};
2     cin >> pStr;
3     if(strcmp(pStr,"AAAA") == 0)
4         AAAA *p =  new AAAA;
5     if(strcmp(pStr,"BBBB") == 0)
6         BBBB *p =  new BBBB;
7     if(strcmp(pStr,"DDDD") == 0)
8         DDDD *p =  new DDDD;

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

 1 void CreateObjectAAAA()
 2 {
 3     AAAA *p =  new AAAA;
 4 }
 5 void CreateObjectBBBB()
 6 {
 7     BBBB *p =  new BBBB;
 8 }
 9 void CreateObjectDDDD()
10 {
11     DDDD *p =  new DDDD;
12 }
13 int main()
14 {
15     char pStr[20] = {0};
16     cin >> pStr;
17     if(strcmp(pStr,"AAAA") == 0)
18         CreateObjectAAAA();
19     if(strcmp(pStr,"BBBB") == 0)
20         CreateObjectBBBB();
21     if(strcmp(pStr,"DDDD") == 0)
22         CreateObjectDDDD();

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

1 struct Node
2 {
3     char pStr[20];
4     void (*pfnCreateObject)();
5     Node* pNext;
6 };

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

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

 1 struct Node
 2 {
 3     char pStr[20];
 4     COObject* (*pfnCreateObject)();
 5     Node* pNext;
 6 };
 7 COObject* CreateObjectAAAA()
 8 {
 9     AAAA *p =  new AAAA;
10     return p;
11 }
12 COObject* CreateObjectBBBB()
13 {
14     BBBB *p =  new BBBB;
15     return p;
16 }
17 COObject* CreateObjectDDDD()
18 {
19     DDDD *p =  new DDDD;
20     return p;
21 }

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

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

 1 #pragma once
 2 class COObject;
 3 struct Node
 4 {
 5     char pStr[20];
 6     COObject* (*pfnCreateObject)();
 7     Node* pNext;
 8 };
 9 class COObject
10 {
11 public:
12     COObject(void);
13     virtual ~COObject(void);
14 public:
15     COObject *Create(const char *pszClassName);
16 };
 1 #include "OObject.h"
 2 #include<string.h>
 3
 4 COObject::COObject(void)
 5 {
 6 }
 7
 8
 9 COObject::~COObject(void)
10 {
11 }
12 COObject *COObject::Create(const char *pszClassName)
13 {
14     Node *pTemp = 0;
15     while(pTemp)
16     {
17         if(strcmp(pTemp->pStr,pszClassName) == 0)
18         {
19             return pTemp->pfnCreateObject();
20         }
21         pTemp = pTemp->pNext;
22     }
23     return 0;
24 }

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

 1 #pragma once
 2 #include"OObject.h"
 3 class AAAA : public COObject
 4 {
 5 public:
 6     AAAA(void);
 7     ~AAAA(void);
 8 public:
 9     static Node node;
10     static COObject*CreateObject();
11 };
 1 #include "AAAA.h"
 2 Node AAAA::node = {"AAAA",0,&AAAA::CreateObject};
 3 COObject*AAAA::CreateObject()
 4 {
 5     return new AAAA;
 6 }
 7
 8 AAAA::AAAA(void)
 9 {
10 }
11
12
13 AAAA::~AAAA(void)
14 {
15 }

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

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

1 #define IMPLEMENT_DYNCREATE(ThisClass)2     Node ThisClass::node = {#ThisClass,0,&ThisClass::CreateObject};3     InitObject init##ThisClass(&ThisClass::node);4     COObject* ThisClass::CreateObject()5     {6         return new ThisClass;7     }

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

原文地址:https://www.cnblogs.com/xgmzhna/p/11072731.html

时间: 2024-11-03 01:56:00

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

C语言动态内存管理

1-概述 动态存储管理的基本问题是:系统如何按请求分配内存,如何回收内存再利用.提出请求的用户可能是系统的一个作业,也可能是程序中的一个变量. 空闲块 未曾分配的地址连续的内存区称为"空闲块". 占用块 已分配给用户使用的地址连续的内存区称为"占用块". 系统刚刚启动时,整个内存可看做一个大的"空闲块",随着用户请求的进入,系统依次分配相应的内存. 在系统运行过程中,内存被分为两大部分:低地址区(若干占用块)和高地址区(空闲块). 经过一段时间后

C++ Primer 学习笔记_34_面向对象编程(5)--虚函数与多态(二):纯虚函数、抽象类、虚析构函数、动态创建对象

C++ Primer 学习笔记_34_面向对象编程(5)--虚函数与多态(二):纯虚函数.抽象类.虚析构函数.动态创建对象 一.纯虚函数 1.虚函数是实现多态性的前提 需要在基类中定义共同的接口 接口要定义为虚函数 2.如果基类的接口没办法实现怎么办? 如形状类Shape 解决方法 将这些接口定义为纯虚函数 3.在基类中不能给出有意义的虚函数定义,这时可以把它声明成纯虚函数,把它的定义留给派生类来做 4.定义纯虚函数: class <类名> { virtual <类型> <函

线性表之顺序存储结构(C语言动态数组实现)

线性表的定义:N个数据元素的有限序列 线性表从存储结构上分为:顺序存储结构(数组)和 链式存储结构(链表) 顺序存储结构:是用一段连续的内存空间存储表中的数据 L=(a1,a2,a3....an) 链式存储结构:是用一段一段连续的内存空间存储表中每一行的数据,段与段之间通过一个引用(指针)相互连接来,形成一个链式的存储结构 看到顺序存储结构的图示,我们可能会马上联想到C语言的数组.是的,数组就是一种典型的顺序存储数据结构.下面我通过一个实例,来实现对顺序存储结构中的数据增.删.改.查的操作. 首

反射之动态创建对象

前言 C#有关反射的话题已经是个老生常谈的话题,也许园友一看这标题都不屑去看了,但是既然拿出来讲必有讲之道理,当然,不喜勿喷,高手请绕道!直入话题. 讨论 定义一个Person类代码如下 1 public class Person 2 { 3 4 /// <summary> 5 /// 年龄 6 /// </summary> 7 public int Age { get; set; } 8 9 /// <summary> 10 /// 姓名 11 /// </su

C语言动态存储分配

动态存储分配 C语言支持动态存储分配,即在程序执行期间分配内存单元的能力,利用动态存储分配,可以根据需要设计扩大(或缩小)的数据结构,虽然可以适用于所有类型的数据,但是动态存储分配更常用于字符串.数组和结构体 本文地址:http://www.cnblogs.com/archimedes/p/c-dynamic-storage-allocation.html,转载请注明源地址. 1.内存分配函数 3种内存分配函数都是声明在<stdlib.h>中: malloc函数--分配内存块,但是不对内存块进

C语言动态内存相关函数

C语言动态内存管理函数有4个,分别为malloc,realloc,calloc和free.malloc函数分配一块堆内存:calloc是malloc的变种,功能相同,有细小的差别:realloc修改原内存块大小:free释放参数指针指向的内存块.下面分别介绍它们的函数原型.函数功能和一些特别的注意事项. Function name 函数原型 函数功能 malloc void * malloc ( size_t size ); 向系统申请分配指定size个字节的内存空间.返回类型是 void* 类

.Net——动态创建对象

刚开始看到这个标题的时候其实我也是很难接受的,duang~因为实在想不出什么时候我要去这样子创建对象,干嘛不new一个呢?但根据学习设计模式的经验来说,有时候,不去new对象才是最灵活的做法. 首先,写个小类拿着玩儿: public class Calculator { private int x; private int y; public Calculator() { x = 0; y = 0; Console.WriteLine("Calculator () invoked");

C语言 动态输入字符串

作者 :卿笃军 很多时候,我们不知道要开辟多大的空间,但是我们又想实现无限制的输入~~~ 这时候,就需要用到动态空间的开辟了. 先简绍2个函数: malloc()  , realloc() 函数名:malloc 原型:externvoid *malloc(unsigned int num_bytes); 功能:在堆中开辟num_bytes个字节的空间 函数名:realloc 原型:externvoid *realloc(void *mem_address, unsigned intnewsize

动态创建对象

C#主要支持 5 种动态创建对象的方式: 1. Type.InvokeMember 2. ContructorInfo.Invoke 3. Activator.CreateInstance(Type) 4. Activator.CreateInstance(assemblyName, typeName) 5. Assembly.CreateInstance(typeName) 最快的是方式 3 ,与 Direct Create 的差异在一个数量级之内,约慢 7 倍的水平.其他方式,至少在 40