您的位置:首页 > 编程语言 > C语言/C++

C++ 反射机制的简单实现

2018-05-15 11:43 411 查看
class_factory.h

#ifndef __CLASSFACTORY_
#define __CLASSFACTORY_

#include <iostream>
#include<string>
#include<map>

//定义函数指针
typedef void* (*create_fun)();

class ClassFactory{
public:
~ClassFactory() {};

//根据类注册时的名字, 创建类实例, 并返回
void* getClassByName(std::string name){
std::map<std::string, create_fun>::iterator it = my_map.find(name);
if (it == my_map.end()) { return NULL; }

create_fun fun = it->second;
if (!fun) { return NULL; }

return fun();
}

//注册类名称与指针函数到映射关系
void registClass(std::string name, create_fun fun){
my_map[name] = fun;
}

//单例模式
static ClassFactory& getInstance(){
static ClassFactory fac;
return fac;
}

private:
ClassFactory() {};  //私有
std::map<std::string, create_fun> my_map;
};

#endif

test.h

#ifndef __TEST_H
#define __TEST_H

#include <iostream>

class Test{
public:
Test(){ std::cout << "call Test Constructor fun" << std::endl; }
~Test(){ std::cout << "call Test Destructor fun" << std::endl; }
void print(){ std::cout << "call Test print fun" << std::endl; }
};

void* create_Test(){
Test *t = new Test;
return (t == NULL)? NULL:t;
}

#endif

main.cpp

#include "test.h"
#include "class_factory.h"

int main(){
//注册
ClassFactory::getInstance().registClass("Test", create_Test);

//获取类对象
Test *t = (Test*)ClassFactory::getInstance().getClassByName("Test");
if (!t){
std::cout << "get instnce Test err;" << std::endl;
return 1;
}

t->print();
delete t;
return 0;
}


Create C++ Object Dynamically

Introduction

C++不像C#和Java那样具有反射的能力,通常不能根据任意一个class name来创建该class的instance。但我们知道在MFC中,任何继承了CObject的类都可以根据其名字来创建实例,它是使用了一些宏。而我从来就不喜欢使用大把的宏,虽然有的时候宏可能比较方便,可能对某些人来说也更美观。

原理很简单——定义一个基类,维护一个其派生类信息(包括派生类的名字和创建实例的函数指针)的列表,而派生类在程序运行的最初始阶段就向基类注册其信息。

Design & Implementation

Base Class—— DynBase

Derived Class—— Any Class Derived from DynBase

DynBase

DynBase.h:

#pragma once

#include <map>
#include <string>

class DynBase;

struct ClassInfo;

bool Register(ClassInfo* ci);

typedef DynBase* (*funCreateObject)();

//Assistant class to create object dynamicly

struct ClassInfo
{
public:
string Type;
funCreateObject Fun;

ClassInfo(string type, funCreateObject fun)
{
Type = type;
Fun = fun;
Register(this);
}
};

//The base class of dynamic created class.
//If you want to create a instance of a class ,you must let
//the class derive from the DynBase.

class DynBase
{
public:
static bool Register(ClassInfo* classInfo);
static DynBase* CreateObject(string type);

private:
static std::map<string,ClassInfo*> m_classInfoMap;
};


DynBase.cpp:

#include "stdafx.h"
#include "DynBase.h"

std::map< string,ClassInfo*> DynBase::m_classInfoMap = std::map<string,ClassInfo*>();

bool DynBase::Register(ClassInfo* classInfo)
{
m_classInfoMap[classInfo->Type] = classInfo;
return true;
}

DynBase* DynBase::CreateObject(string type)
{
if ( m_classInfoMap[type] != NULL )
{
return m_classInfoMap[type]->Fun();
}
return NULL;
}

bool Register(ClassInfo* ci)
{
return DynBase::Register(ci);
}


Derived Class

DerivedClass.h:

class DerivedClass : public DynBase
{
public:
virtual ~ DerivedClass ();

DerivedClass ();
static DynBase* CreateObject(){return new DerivedClass ();}

private:
static ClassInfo* m_cInfo;
};

DerivedClass.cpp:

#include "stdafx.h"
#include "DynBase.h"
#include "DerivedClass.h"

DerivedClass::~ DerivedClass ()
{
// ToDo: Add your specialized code here and/or call the base class
}

DerivedClass:: DerivedClass ()
{

}

ClassInfo* DerivedClass::m_cInfo = new ClassInfo(“DerivedClass”,(funCreateObject)( DerivedClass::CreateObject));


How to Use

int _tmain(int argc, _TCHAR* argv[])
{
DerivedClass * instance = (DerivedClass *)DynBase::CreateObject(“DerivedClass”);
//do something
system("pause");
return 0;
}

Postscript

C++虽然没有反射的功能也能在一定的情况下根据类名来动态创建其实例,虽然使用了全局静态函数以及静态成员这样不是很理想的方法——可也只能用这样的方法了。在我们使用工厂模式的时候,可以使用这样的方法来创建某产品的实例了,而不是使用大把的switch-case语句了。

https://www.cnblogs.com/xudong-bupt/p/6643721.html
https://blog.csdn.net/klarclm/article/details/7352091
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: