美文网首页
C++: 反射的简单实现

C++: 反射的简单实现

作者: 赵伯舟 | 来源:发表于2018-10-02 22:57 被阅读22次

可先参考:链接

问题引入

如何根据一个字符串(类的名称),创建出一个对象

当我们获得了一个string str = "class_name",那么如何根据这个str来创建一个对象?这时候就需要用到反射。个人对反射的简单理解就是一个字面量来动态创建出一个对象,并可获取对象的成员信息。Java和C#都有完整的反射机制,而C++至今还没有,只能自己动手实现

实现思路

  1. 可以用一个map来存储类名-构造函数这样的键值对,每新增一个类,就在这个map“注册”一个键值对
  2. 因为这个map是一个全局都会用到的,所以可以使用单例模式
  3. 在进入main函数之前,这个map就应该生成好,即每一个类在实例化之前就执行了“注册”的代码,那怎么在main函数之前就执行“注册”代码?答案可参见下面的代码实现

代码实现

#include <iostream>
#include <map>
#include <memory>

#define FUNC function<void*(void)>

using namespace std;

class Reflector
{
private:
    map<std::string, FUNC>objectMap;
    static shared_ptr<Reflector> ptr;

public:
    void* CreateObject(const string &str)
    {
        for (auto & x : objectMap)
        {
            if(x.first == str)
                return x.second();
        }
        return nullptr;
    }

    void Register(const string &class_name, FUNC && generator)
    {
        objectMap[class_name] = generator;
    }

    static shared_ptr<Reflector> Instance()
    {
        if(ptr == nullptr)
        {
            ptr.reset(new Reflector());
        }

        return ptr;
    }

};

shared_ptr<Reflector> Reflector::ptr = nullptr;

class RegisterAction
{
public:
    RegisterAction(const string &class_name, FUNC && generator)
    {
        Reflector::Instance()->Register(class_name, forward<FUNC>(generator));
    }
};

#define REGISTER(CLASS_NAME) \
RegisterAction g_register_action_##CLASS_NAME(#CLASS_NAME, []()\
{\
    return new CLASS_NAME(); \
});


class Base
{
public:
    explicit Base() = default;
    virtual void Print()
    {
        cout << "Base" << endl;
    }
};
REGISTER(Base);

class DeriveA : public Base
{
public:
    void Print() override
    {
        cout << "DeriveA" << endl;
    }
};
REGISTER(DeriveA);

class DeriveB : public Base
{
public:
    void Print() override
    {
        cout << "DeriveB" << endl;
    }
};
REGISTER(DeriveB);

int main()
{
    shared_ptr<Base> p1((Base*)Reflector::Instance()->CreateObject("Base"));
    p1->Print();

    shared_ptr<Base> p2((Base*)Reflector::Instance()->CreateObject("DeriveA"));
    p2->Print();

    shared_ptr<Base> p3((Base*)Reflector::Instance()->CreateObject("DeriveB"));
    p3->Print();
}

上述代码中的Reflector使用了单例模式,维护一个存储[类名: 构造器]map,每新增一个类,就会通过宏REGISTER来为这个新增一个构造器(其实就是一个lambda表达式,使用new返回一个指针),并用这个构造器和类名生成一个RegisterAction实例,而在RegisterAction的构造函数中进行了“注册”,即通过实例化一个RegisterActionmain函数之前完成了注册

相关文章

  • C++: 反射的简单实现

    可先参考:链接 问题引入 如何根据一个字符串(类的名称),创建出一个对象 当我们获得了一个string str =...

  • c++实现反射

    反射机制在java中是一个非常重要的特性,比如在spring框架中,就使用了xml + 反射来完成类的动态扩展。简...

  • 【Java 进阶】Java 反射

    反射:获取Class中所有字段(Field)与方法(Method),并实现调用(invoke) Java 反射简单...

  • Ruby多态函数的常用实现方法

    Ruby不支持类似C++的多态。 可以使用他的反射方法实现。 例如 def some_fn option ca...

  • java反射

    1.反射是java被视为动态语言的关键。 (动态语言:python,c#;静态:c/c++) 优点:实现动态创建对...

  • PHP反射机制Reflection

    反射机制简介 在面向对象编程中,对象被系统赋予了自省的能力,而实现这个自省的过程就是反射。 ​反射,简单理解就是根...

  • 2_11基数排序

    C++的queue实现 C++ vector 实现 python 实现

  • C++反射的一种实现

    C++反射的实现需要解决的核心问题是怎么保持一个存储了类名到构造函数的方法。在上一篇我使用了宏定义在服务启动的时候...

  • iOS - block - C++基础分析

    [toc] 参考 block - C++基础分析 获取 C++源码 在 main.m 中, 用 OC 实现一个简单...

  • 基于c++的哈夫曼编码

    c++实现哈夫曼编码,本例中采取了相对简单易懂的构建方式,与其他相类似的代码相比,更为直观和简练。 C++实现的哈...

网友评论

      本文标题:C++: 反射的简单实现

      本文链接:https://www.haomeiwen.com/subject/bioaoftx.html