参考了wxWidgets的相关代码,并进行简化,同时借鉴了网上的相关内容,改进之处在于,只需要继承基本类Object,在类的头文件中定义宏,DECLARE_CLASS(类名),在类的实现文件中定义宏,IMPLEMENT_CLASS(类名),即可,欢迎指正。 
代码以来的库都是C++标准库,所以不需要额外添加库。 
例如:

#include<iostream>
#include<cstring>
#include "DynBase.h"
using namespace std;
 
class A : public Object
{
 DECLARE_CLASS(A)
public :
A(){cout<<hex<<(long)this<<" A constructor!"<<endl;}
~A(){cout<<hex<<(long)this<<" A destructor!"<<endl;}
};
IMPLEMENT_CLASS(A)
 
class B : public Object
{
 DECLARE_CLASS(B)
public :
B(){cout<<hex<<(long)this<<" B constructor!"<<endl;}
~B(){cout<<hex<<(long)this<<" B destructor!"<<endl;}
};
IMPLEMENT_CLASS(B)
 
int main()
{
Object* p = Object::CreateObject("A");
delete p;
    system("pause");
    return 0;
}
 
 
标签: <无>
 

代码片段(3)[全屏查看所有代码]

1. [文件] DynBase.cpp ~ 781B     下载(284)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "StdAfx.h"
#include <map>
#include "DynBase.h"
  
static std::map< string,ClassInfo*> *classInfoMap = NULL;
using namespace std;
IMPLEMENT_CLASS(Object)
bool Object::Register(ClassInfo* ci)
{
    if(!classInfoMap)   {
        classInfoMap = new std::map< string,ClassInfo*>();
    }
    if(ci)  {
        if(classInfoMap->find(ci->m_className) == classInfoMap->end()){
            classInfoMap->insert(std::map< string,ClassInfo*>::value_type(ci->m_className,ci));
        }
    }
    return true;
}
Object* Object::CreateObject(std::string name)
{
    std::map< string,ClassInfo*>::const_iterator iter = classInfoMap->find(name);
    if(classInfoMap->end() != iter)  {
        return iter->second->CreateObject();
    }  
    return NULL;
}
 
bool Register(ClassInfo* ci)
{
    return Object::Register(ci);
}

2. [文件] DynBase.h ~ 1KB     下载(267)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#ifndef __DYNBASE_H__
#define __DYNBASE_H__
#include <string>
 
class Object;
class ClassInfo;
 
typedef Object* (*ObjectConstructorFn)(void);
bool Register(ClassInfo* ci);
using namespace std;
 
class ClassInfo
{
public:
    ClassInfo(const std::string className,ObjectConstructorFn ctor)
    :m_className(className) ,m_objectConstructor(ctor)
    {
        Register(this);
    }
    virtual ~ClassInfo(){}
    Object* CreateObject()const { return m_objectConstructor ? (*m_objectConstructor)() : 0;    }
    bool IsDynamic()const { return NULL != m_objectConstructor;}
    const std::string GetClassName()const { return m_className;}
    ObjectConstructorFn GetConstructor()const{ return m_objectConstructor;}
public:
    string m_className;
    ObjectConstructorFn m_objectConstructor;
};
 
#define DECLARE_CLASS(name) \
    protected: \
        static ClassInfo ms_classinfo; \
    public:  \
        virtual ClassInfo* GetClassInfo() const; \
        static Object* CreateObject();
 
#define IMPLEMENT_CLASS_COMMON(name,func) \
    ClassInfo name::ms_classinfo((#name), \
             (ObjectConstructorFn) func); \
                          \
    ClassInfo *name::GetClassInfo() const \
        {return &name::ms_classinfo;}
 
#define IMPLEMENT_CLASS(name)            \
    IMPLEMENT_CLASS_COMMON(name,name::CreateObject) \
    Object* name::CreateObject()                   \
        { return new name;}
 
 
class Object
{
    DECLARE_CLASS(Object)
public:
    Object(){}
    virtual ~Object(){}
    static bool Register(ClassInfo* ci);
    static Object* CreateObject(string name);
};
 
 
#endif

3. [文件] test.cpp ~ 579B     下载(236)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<iostream>
#include<cstring>
#include "DynBase.h"
using namespace std;
 
class A : public Object
{
    DECLARE_CLASS(A)
public :
    A(){cout<<hex<<(long)this<<" A constructor!"<<endl;}
    ~A(){cout<<hex<<(long)this<<" A destructor!"<<endl;}
};
IMPLEMENT_CLASS(A)
 
class B : public Object
{
    DECLARE_CLASS(B)
public :
    B(){cout<<hex<<(long)this<<" B constructor!"<<endl;}
    ~B(){cout<<hex<<(long)this<<" B destructor!"<<endl;}
};
IMPLEMENT_CLASS(B)
 
int main()
{
    Object* p = Object::CreateObject("A");
    delete p;
    system("pause");
    return 0;
}

C++反射实现(转)的更多相关文章

  1. 隐私泄露杀手锏 —— Flash 权限反射

    [简版:http://weibo.com/p/1001603881940380956046] 前言 一直以为该风险早已被重视,但最近无意中发现,仍有不少网站存在该缺陷,其中不乏一些常用的邮箱.社交网站 ...

  2. Java学习之反射机制及应用场景

    前言: 最近公司正在进行业务组件化进程,其中的路由实现用到了Java的反射机制,既然用到了就想着好好学习总结一下,其实无论是之前的EventBus 2.x版本还是Retrofit.早期的View注解框 ...

  3. 关于 CSS 反射倒影的研究思考

    原文地址:https://css-tricks.com/state-css-reflections 译者:nzbin 友情提示:由于演示 demo 的兼容性,推荐火狐浏览.该文章篇幅较长,内容庞杂,有 ...

  4. 编写高质量代码:改善Java程序的151个建议(第7章:泛型和反射___建议106~109)

    建议106:动态代理可以使代理模式更加灵活 Java的反射框架提供了动态代理(Dynamic Proxy)机制,允许在运行期对目标类生成代理,避免重复开发.我们知道一个静态代理是通过主题角色(Prox ...

  5. 运用Mono.Cecil 反射读取.NET程序集元数据

    CLR自带的反射机智和API可以很轻松的读取.NET程序集信息,但是不能对程序集进行修改.CLR提供的是只读的API,但是开源项目Mono.Cecil不仅仅可以读取.NET程序集的元数据,还可以进行修 ...

  6. .NET面试题系列[6] - 反射

    反射 - 定义,实例与优化 在面试中,通常会考察反射的定义(操作元数据),可以用反射做什么(获得程序集及其各个部件),反射有什么使用场景(ORM,序列化,反序列化,值类型比较等).如果答得好,还可能会 ...

  7. .NET基础拾遗(4)委托、事件、反射与特性

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...

  8. C++的性能C#的产能?! - .Net Native 系列五:.Net Native与反射

    此系列系小九的学堂原创翻译,翻译自微软官方开发向导,一共分为六个主题.本文是第五个主题:.Net Native与反射. 向导文链接:<C++的性能C#的产能?! - .Net Native 系列 ...

  9. [源码]Literacy 快速反射读写对象属性,字段

    Literacy 说明 Literacy使用IL指令生成方法委托,性能方面,在调用次数达到一定量的时候比反射高很多 当然,用IL指令生成一个方法也是有时间消耗的,所以在只使用一次或少数几次的情况,不但 ...

  10. SI与EMI(一) - 反射是怎样影响EMI

    Mark为期两天的EMC培训中大概分成四个时间差不多的部分,简单来说分别是SI.PI.回流.屏蔽.而在信号完整性的书籍中,也会把信号完整性分为:1.信号自身传输的问题(反射,损耗):2.信号与信号之间 ...

随机推荐

  1. Mock an function to modify partial return value by special arguments on Python

    Mock an function to modify partial return value by special arguments on Python python mock一个带参数的方法,修 ...

  2. go关键字之struct定义声明方式

    type Student struct{ name string age int } var stu Student stu.name,stu.age = "张三”,10 stu2 := S ...

  3. Web容器初始化过程

    一.SpringMVC启动过程 Spring的MVC是基于Servlet功能实现的,每个web工程中都有一个web.xml文件,web容器在启动的时候会加载这个配置文件,当一个web应用加载到web容 ...

  4. 关于linux下ntp时间同步服务的安装与配置

    1.安装ntp服务,要使用时间同步.那么服务端与客户端都需要使用如下命令安装NTP软件包 [root@ ~]# yum install ntp -y 2.如果只是作为客户端的话,配置则可以非常简单,编 ...

  5. 数据共享Manager

    将数据设置成共享数据,一个进程修改了数据,另外一个进程就能就接受的被修改的数据. 起50个进程让他们都去操作一个数据: from multiprocessing import Process, Man ...

  6. PHP(Dom操作的一些基础)

    重点!! //DOM操作: // 核心思想:找到元素 操作元素// js找元素 会返回元素对象:// document.getElementById("dd");唯一确定// 返回 ...

  7. Java 实现 AES 加解密

    毕业课题中需要使用加解密算法,要求加解密前后的数据长度不会变化,查了一些资料,发现可以采用AES加密的CFB跟OFB模式是无填充的模式,可以保持加解密前后数据的长度相等.下面上代码: import j ...

  8. iota

    这算法由SGI专属,并不在STL标准之列.它用来设定某个区间的内容,使其内的每一个元素从指定的value值开始,呈现递增状态.它改变了区间内容,所以是一种质变算法. template <clas ...

  9. 洛谷P3387 【模板】缩点

    题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只 ...

  10. git从已有分支拉新分支开发

    开发过程中经常用到从master分支copy一个开发分支,下面我们就用命令行完成这个操作: 1. 切换到被copy的分支(master),并且从远端拉取最新版本 $git checkout maste ...