[C++学习笔记14]动态创建对象

 
  1. C#/Java中的反射机制
      动态获取类型信息(方法与属性)
        动态创建对象
        动态调用对象的方法
        动态操作对象的属性
      前提:需要给每个类添加元数据

  2. 动态创建对象
      实现原理:通过定义一个宏REGISTER_CLASS,传入类名,在该宏中创建一个类独有的Register类,类中定义静态方法创建对象(new)并返回指针,并在该类中定义一个公共Register类的成员变量,在该公共Register类的构造函数中调用工厂类的Register方法注册类名与创建对象的函数指针到map,在工厂类中定义静态方法实现在map查找具体类名对应的创建函数,并返回调用即可。
      
    #ifndef __DYN_BASE_H__
    #define __DYN_BASE_H__ #include <map>
    #include <string>
    using namespace std; typedef void* (*CREATE_FUNC)(); class DynObjectFactory {
    public:
    static void *createObject(const string &name)
    {
    map<string, CREATE_FUNC>::const_iterator it;
    it = mapCls_.find(name); if (it == mapCls_.end())
    return nullptr; return it->second();
    } static void Register(const string &name, CREATE_FUNC func)
    {
    mapCls_[name] = func;
    } private:
    static map<string, CREATE_FUNC> mapCls_;
    }; // g++
    // __attribute ((weak))
    __declspec(selectany) map<string, CREATE_FUNC> DynObjectFactory::mapCls_; class Register {
    public:
    Register(const string &name, CREATE_FUNC func)
    {
    DynObjectFactory::Register(name, func);
    }
    }; #define REGISTER_CLASS(class_name) \
    class class_name##Register{ \
    public: \
    static void* newInstance() \
    { \
    return new class_name; \
    } \
    private: \
    static Register reg_; \
    }; \
    Register class_name##Register::reg_(#class_name, class_name##Register::newInstance); #endif // __DYN_BASE_H__
    复制代码 复制代码
    #ifndef __SHAPE_H__
    #define __SHAPE_H__ #include <iostream>
    #include <vector>
    #include <string>
    using namespace std; class Shape {
    public:
    virtual void Draw() = ;
    virtual ~Shape() {}
    }; class Circle : public Shape {
    public:
    void Draw();
    ~Circle();
    }; class Rectangle : public Shape {
    public:
    void Draw();
    ~Rectangle();
    }; class Square : public Shape {
    public:
    void Draw();
    ~Square();
    }; #endif // __SHAPE_H__
    复制代码 复制代码
    #include "Shape.h"
    #include "DynBase.h" void drawAllShapes(const vector<Shape *> v)
    {
    vector<Shape *>::const_iterator it;
    for (it = v.begin(); it != v.end(); ++it) {
    (*it)->Draw();
    }
    } void deleteAllShapes(const vector<Shape *> v)
    {
    vector<Shape *>::const_iterator it;
    for (it = v.begin(); it != v.end(); ++it) {
    delete (*it);
    }
    } int main(void)
    {
    //Shape s; // Error, 抽象类不能实例化对象
    vector<Shape *> v;
    Shape *ps = NULL; ps = static_cast<Shape *>(DynObjectFactory::createObject("Circle"));
    v.push_back(ps);
    ps = static_cast<Shape *>(DynObjectFactory::createObject("Square"));
    v.push_back(ps);
    ps = static_cast<Shape *>(DynObjectFactory::createObject("Rectangle"));
    v.push_back(ps); drawAllShapes(v);
    deleteAllShapes(v); // 未将Shape基类的析构函数声明为虚函数之前,并不会调用各个派生类的析构函数
    // 声明为虚函数之后,就会调用了
    return ;
    }
    复制代码 复制代码
    #include "Shape.h"
    #include "DynBase.h" void Circle::Draw()
    {
    cout << "Circle Draw ... " << endl;
    } Circle::~Circle()
    {
    cout << "~Circle ... " << endl;
    } void Rectangle::Draw()
    {
    cout << "Rectangle Draw .." << endl;
    } Rectangle::~Rectangle()
    {
    cout << "~Rectangle ... " << endl;
    } void Square::Draw()
    {
    cout << "Square Draw ..." << endl;
    } Square::~Square()
    {
    cout << "~Square ... " << endl;
    } REGISTER_CLASS(Circle)
    REGISTER_CLASS(Square)
    REGISTER_CLASS(Rectangle)

http://www.cnblogs.com/ifpelset/articles/4544750.html

[C++学习笔记14]动态创建对象(定义静态方法实现在map查找具体类名对应的创建函数,并返回函数指针,map真是一个万能类)good的更多相关文章

  1. Mybatis学习笔记14 - 动态sql之foreach标签

    一.查询给定集合中员工id对应的所有员工信息 示例代码: 接口定义: package com.mybatis.dao; import com.mybatis.bean.Employee; import ...

  2. 【转】 C#学习笔记14——Trace、Debug和TraceSource的使用以及日志设计

    [转] C#学习笔记14——Trace.Debug和TraceSource的使用以及日志设计 Trace.Debug和TraceSource的使用以及日志设计   .NET Framework 命名空 ...

  3. SQL反模式学习笔记14 关于Null值的使用

    目标:辨别并使用Null值 反模式:将Null值作为普通的值,反之亦然 1.在表达式中使用Null: Null值与空字符串是不一样的,Null值参与任何的加.减.乘.除等其他运算,结果都是Null: ...

  4. MyBatis:学习笔记(4)——动态SQL

    MyBatis:学习笔记(4)——动态SQL 如果使用JDBC或者其他框架,很多时候需要你根据需求手动拼装SQL语句,这是一件非常麻烦的事情.MyBatis提供了对SQL语句动态的组装能力,而且他只有 ...

  5. 并发编程学习笔记(14)----ThreadPoolExecutor(线程池)的使用及原理

    1. 概述 1.1 什么是线程池 与jdbc连接池类似,在创建线程池或销毁线程时,会消耗大量的系统资源,因此在java中提出了线程池的概念,预先创建好固定数量的线程,当有任务需要线程去执行时,不用再去 ...

  6. SpringBoot学习笔记:动态数据源切换

    SpringBoot学习笔记:动态数据源切换 数据源 Java的javax.sql.DataSource接口提供了一种处理数据库连接的标准方法.通常,DataSource使用URL和一些凭据来建立数据 ...

  7. Ext.Net学习笔记14:Ext.Net GridPanel Grouping用法

    Ext.Net学习笔记14:Ext.Net GridPanel Grouping用法 Ext.Net GridPanel可以进行Group操作,例如: 如何启用Grouping功能呢?只需要在Grid ...

  8. Web Service学习笔记:动态调用WebService

    原文:Web Service学习笔记:动态调用WebService 多数时候我们通过 "添加 Web 引用..." 创建客户端代理类的方式调用WebService,但在某些情况下我 ...

  9. golang学习笔记14 golang substring 截取字符串

    golang学习笔记14 golang substring 截取字符串golang 没有java那样的substring函数,但支持直接根据 index 截取字符串mystr := "hel ...

随机推荐

  1. js进阶ajax的XMLHttpRequest对象的status和statustext属性(如果ajax和php联合使用的话:open连接服务器的第二个参数文件路径改成请求php的url即可)

    js进阶ajax的XMLHttpRequest对象的status和statustext属性(如果ajax和php联合使用的话:open连接服务器的第二个参数文件路径改成请求php的url即可) 一.总 ...

  2. ModSecurity防御暴力破解

    http://www.modsecurity.org/ ModSecurity防御暴力破解 在阅读本文前,先简单了解下什么是ModSecurity,ModSecurity是一个入侵探测与阻止的引擎.它 ...

  3. POJ 1751 Highways (ZOJ 2048 ) MST

    http://poj.org/problem?id=1751 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2048 题目大 ...

  4. Size Balanced Tree(SBT树)整理

    不想用treap和Splay,那就用SB树把,哈哈,其实它一点也SB,厉害着呢. 先膜拜一下作者陈启峰.Orz 以下内容由我搜集整理得来. 一.BST及其局限性 二叉查找树(Binary Search ...

  5. 《大型网站技术架构》1:概述 分类: C_OHTERS 2014-05-07 20:40 664人阅读 评论(0) 收藏

    参考自<大型网站技术架构>第1~3章 1.大型网站架构演化发展历程 (1)初始阶段的网站架构:一台服务器分别作为应用.数据.文件服务器 (2)应用服务和数据服务分离:三台服务器分别承担上述 ...

  6. js javascript正则

    var re = new RegExp("^[0-9]$"); 或者 var re2 = /^\d$/;//这个好像兼容性更好,比如你在上面的语句里面写\d,就总是返回false, ...

  7. RSA公钥、私钥、签名和验签

    1 RSA加密算法介绍 RSA又叫非对称加密算法,这类加密算法有一对秘钥,其中一个用来加密一个用来解密.这一对秘钥中你可以选择一个作为私钥(自己保存),另一个作为公钥(对外公开).用私钥加密的内容只能 ...

  8. windows下python安装uwsgi

    1.使用pip安装 pip install uwsgi 报错:os没有uname() 解决: 定位到uwsgiconfig.py文件中,首先import platform后,将os.unam()都改为 ...

  9. Colder框架硬核更新(Sharding+IOC)

    目录 引言 控制反转 读写分离分库分表 理论基础 设计目标 现状调研 设计思路 实现之过五关斩六将 动态对象 动态模型缓存 数据源移植 查询表达式树深度移植 数据合并算法 事务支持 实际使用 展望未来 ...

  10. ArcSDE中Compress与Compact的区别

    原文 ArcSDE中Compress与Compact的区别 附件一”为两种数据库需要的管理工作.      与所表示的含义与操作是不同的.     对于来说,Compressing与Smart Dat ...