从零开始学C++之动态创建对象
回顾前面的文章,实现了一个简单工厂模式来创建不同类对象,但由于c++没有类似new "Circle"之类的语法,导致CreateShape 函
数中需要不断地ifelse地去判断,如果有多个不同类对象需要创建,显然这是很费神的,下面通过宏定义注册的方法来实现动态创
建对象。
Shape.h:
|
1 |
#ifndef _SHAPE_H_
#define _SHAPE_H_ class Shape class Circle : class Square : class Rectangle : #endif |
Shape.cpp:
|
1 |
#include
"Shape.h" #include "DynBase.h" #include <iostream> using namespace std; void Circle::Draw() void Square::Draw() void Rectangle::Draw() Rectangle::~Rectangle() REGISTER_CLASS(Circle); |
DynBase.h:
|
1 |
#ifndef _DYN_BASE_H_
#define _DYN_BASE_H_ #include <map> typedef class DynObjectFactory } static // g++ class Register #define REGISTER_CLASS(class_name) \ #endif |
DynTest.cpp:
|
1 |
#include
"Shape.h" #include "DynBase.h" #include <iostream> #include <vector> #include <string> using namespace std; void DrawAllShapes( void DeleteAllShapes( int main( Shape *ps; DrawAllShapes(v); return |
在DynBase.h 中#define了一个宏定义REGISTER_CLASS(class_name),且在Shape.cpp 中调用宏定义,拿REGISTER_CLASS(Circle);
来说,程序编译预处理阶段会被替换成:
class CircleRegister {
public:
static void* NewInstance()
{
return newCircle;
}
private:
static Register reg_;
};
Register CircleRegister::reg_("Circle",CircleRegister::NewInstance);
也即定义了一个新类,且由于含有static 成员,则在main函数执行前先执行初始化,调用Register类构造函数,在构造函数中调用
DynObjectFactory::Register(name, func); 即调用DynObjectFactory 类的静态成员函数,在Register函数中通过map容器完成了
字符串与函数指针配对的注册,如mapCls_[name] = func;
进入main函数,调用DynObjectFactory::CreateObject("Circle") ,CreateObject函数中通过string找到对应的函数指针
(NewInstance),并且调用后返回创建的对象指针,需要注意的是 return it->second(); 中it->second 是函数指针,后面加括
号表示调用这个函数。对宏定义中的#,##用法不熟悉的可以参考这里。
这样当需要创建多个不同类对象的时候,就不再需要写很多ifelse的判断了。
参考:
C++ primer 第四版
Effective C++ 3rd
C++编程规范
从零开始学C++之动态创建对象的更多相关文章
- (43). Spring Boot动态数据源(多数据源自动切换)【从零开始学Spring Boot】
在上一篇我们介绍了多数据源,但是我们会发现在实际中我们很少直接获取数据源对象进行操作,我们常用的是jdbcTemplate或者是jpa进行操作数据库.那么这一节我们将要介绍怎么进行多数据源动态切换.添 ...
- 从零开始学 Web 之 JavaScript(五)面向对象
大家好,这里是「 Daotin的梦呓 」从零开始学 Web 系列教程.此文首发于「 Daotin的梦呓 」公众号,欢迎大家订阅关注.在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识 ...
- 从零开始学 Java - Spring 集成 ActiveMQ 配置(二)
从上一篇开始说起 上一篇从零开始学 Java - Spring 集成 ActiveMQ 配置(一)文章中讲了我关于消息队列的思考过程,现在这一篇会讲到 ActivMQ 与 Spring 框架的整合配置 ...
- 从零开始学 Java - Spring 一主多从、多主多从 数据库配置
待会苹果要开发布会 我写完这篇文章就准备去看发布会了,因为我买了好几包瓜子和啤酒.由于苹果的保密做的越来越差劲,该曝光的信息差不多全部曝光了,我们这种熬夜看发布会的只不过是让这些信息更加真实,或者说是 ...
- 从零开始学 Java - Spring AOP 实现主从读写分离
深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...
- 从零开始学Bootstrap(2)
继从零开始学Bootstrap(1)后,我们需要实际做一些页面,边学边做.因为前端是一项非常注意实践的技术,知识点太多.太琐碎了,所以我们只能边学边做.根据我们想要做的效果,去查相应的资料.不要想着把 ...
- 从零开始学Sketch——进阶篇-b
从零开始学Sketch——进阶篇 Sketch是一款矢量绘图应用,而矢量绘图无疑是目前进行网页.图标以及界面设计的最好方式. 在初识了Sketch的界面布局和基础工具之后,我们就可以开始进入高阶的Sk ...
- 57. Spring 自定义properties升级篇【从零开始学Spring Boot】
之前在两篇文章中都有简单介绍或者提到过 自定义属性的用法: 25.Spring Boot使用自定义的properties[从零开始学Spring Boot] 51. spring boot属性文件之多 ...
- 从零开始学 Web 系列教程
大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新…… github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:http:/ ...
随机推荐
- 【从零开始,从内核驱动驱动到用户空间调用】编写第一个linux驱动,通过端口访问I/O寄存器。
目的: 通过I/O端口方式访问RTC的秒寄存器: 由于本人从来没看过linux方面的书籍,也只是会在终端用些常用的命令而已,这次老大叫我学着通过I/O端口方式直接去读写寄存器.于是我在google中搜 ...
- perl 继承 @ISA
12.5 类继承 对Perl的对象剩下的内容而言,从一个类继承另外一个类并不需要给这门语法增加特殊的语法,当你调用一个方法的时候, 如果Perl在调用者的包里找不到这个字过程,那么他就检查@ISA数组 ...
- Adrnoid开发系列(二十五):使用AlertDialog创建各种类型的对话框
AlertDialog能够生成各种内容的对话框.可是每种对话框都会有这样的的结构: 类似下边这样的的: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTA ...
- 用QT打开网页
原地址:http://blog.csdn.net/fjb2080/article/details/8136084 1.用qlabel. QLabellabel->setText(tr(" ...
- hbase:应用开发
开发环境: hadoop: hadoop-1.1.2 hbase: hbase-0.94.11-security eclipse:Juno Service Release 2 配置Eclipse 通过 ...
- haproxy timeout server 46000 后台超时时间
[root@wx03 ~]# sh ./1.sh Wed Jul 6 19:54:40 CST 2016 <html><body><h1>504 Gateway T ...
- Tomcat 用户配置
如果你没有改变任何配置文件,请检查文件conf / tomcat用户.xml在你安装.该文件必须包含凭证让你使用这个应用. 例如,添加一个用户名为tomcat manager gui角色s3cret密 ...
- Indy10.2.5的危险做法
为了排查一个Bug今天无意看了看Indy源码,结果吓了一跳.TIdIOHandler.ReadLongWord函数用于读取通讯数据并转换成LongWord类型返回,它做用了一种危险的做法可能会导致数据 ...
- spring mvc接收JSON格式的参数
1.配置spring解析json的库 <dependency> <groupId>org.codehaus.jackson</groupId> ...
- uva 1343 非原创
uva1343 原作者 题目题意是:给你的棋盘,在A-H方向上可以拨动,问你最少拨动几次可以是中心图案的数字一致 解题思路:回溯法,剪枝 其中要把每次拨动的字母所代表的位置提前用数组表示: 然后在如果 ...