ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c++的反射的demo

2021-04-04 20:31:02  阅读:179  来源: 互联网

标签:__ 反射 TestClassB demo void c++ className include ClassFactory


c++的反射的demo

一个基本例子

reflection.cpp

// 工厂类的定义
#include <map>
#include <iostream>
#include <string>
using namespace std;
typedef void* (*PTRCreateObject)(void);
class ClassFactory {
private:
    map<string, PTRCreateObject> m_classMap ;
    ClassFactory(){}; //构造函数私有化

public:
    void* getClassByName(string className);
    void registClass(string name, PTRCreateObject method) ;
    static ClassFactory& getInstance() ;
};
// 工厂类的实现
// brief: 获取工厂类的单个实例对象
ClassFactory& ClassFactory::getInstance(){
    static ClassFactory sLo_factory;
    return sLo_factory ;
}

// brief: 通过类名称字符串获取类的实例
void* ClassFactory::getClassByName(string className){
    map<string, PTRCreateObject>::const_iterator iter;
    iter = m_classMap.find(className) ;
    if ( iter == m_classMap.end() )
        return NULL ;
    else
        return iter->second() ;
}
// brief: 将给定的类名称字符串和对应的创建类对象的函数保存到map中
void ClassFactory::registClass(string name, PTRCreateObject method){
    m_classMap.insert(pair<string, PTRCreateObject>(name, method)) ;
}
class RegisterAction {
public:
    RegisterAction(string className,PTRCreateObject ptrCreateFn) {
        ClassFactory::getInstance().registClass(className, ptrCreateFn);
    }
};
#define REGISTER(className)                                             \
    className* objectCreator##className(){                              \
        return new className;                                           \
    }                                                                   \
    RegisterAction g_creatorRegister##className(                        \
        #className,(PTRCreateObject)objectCreator##className)


// test class
class TestClass {
public:
    void m_print() {
        cout<<"hello TestClass"<<endl;
    };
};
REGISTER(TestClass);

int main(int argc,char* argv[]) {
    TestClass* ptrObj=(TestClass*)ClassFactory::getInstance().getClassByName("TestClass");
    ptrObj->m_print();
}

把这个改造成:调用方不改,底层so可以改的方式

先定义反射工具类
reflection.h

// 工厂类的定义
#ifndef __hao_ClassFactory__
#define __hao_ClassFactory__
#include <map>
#include <string>
using namespace std;
typedef void* (*PTRCreateObject)(void);
class ClassFactory {
private:
    map<string, PTRCreateObject> m_classMap ;
    ClassFactory(){}; //构造函数私有化

public:
    void* getClassByName(string className);
    void registClass(string name, PTRCreateObject method) ;
    static ClassFactory& getInstance() ;
};

class RegisterAction {
public:
    RegisterAction(string className,PTRCreateObject ptrCreateFn) {
        ClassFactory::getInstance().registClass(className, ptrCreateFn);
    }
};
#define REGISTER(className)                                             \
    className* objectCreator##className(){                              \
        return new className;                                           \
    }                                                                   \
    RegisterAction g_creatorRegister##className(                        \
        #className,(PTRCreateObject)objectCreator##className)

#endif

实现类:

// 工厂类的定义
#include <map>
#include <iostream>
#include <string>
#include <reflection.h>
// 工厂类的实现
// brief: 获取工厂类的单个实例对象
ClassFactory& ClassFactory::getInstance(){
    static ClassFactory sLo_factory;
    return sLo_factory ;
}
// brief: 通过类名称字符串获取类的实例
void* ClassFactory::getClassByName(string className){
    map<string, PTRCreateObject>::const_iterator iter;
    iter = m_classMap.find(className) ;
    if ( iter == m_classMap.end() )
        return NULL ;
    else
        return iter->second() ;
}
// brief: 将给定的类名称字符串和对应的创建类对象的函数保存到map中
void ClassFactory::registClass(string name, PTRCreateObject method){
    m_classMap.insert(pair<string, PTRCreateObject>(name, method)) ;
}

生成工具类动态库

g++ -std=c++11 -fpic -shared -o libreflection.so reflection.cpp -I.

定义接口

#ifndef __TestClass__
#define __TestClass__

#include <map>
#include <iostream>
#include <string>
using namespace std;

// test class
class TestClass {
public:
    virtual void m_print() = 0;
//    void m_print() {
//        cout<<"hello TestClass"<<endl;
//    };
};
//REGISTER(TestClass);

#endif

主函数为

#include <map>
#include <iostream>
#include <string>
#include <reflection.h>
#include <TestClass.h>
#include <main.h>
using namespace std;

int main(int argc,char* argv[]) {
   cout << "argv 1: "<<  argv[1] << endl;
   //TestClass* ptrObj=(TestClass*)ClassFactory::getInstance().getClassByName("TestClassA");
   TestClass* ptrObj=(TestClass*)ClassFactory::getInstance().getClassByName(argv[1]);
   ptrObj->m_print();
}

main.h里只定义:

#include <TestClassA.h>
#include <TestClassB.h>

具体的实现TestClassA.h为

#ifndef __TestClassA__
#define __TestClassA__
#include <TestClass.h>
#include <reflection.h>
#include <iostream>
using namespace std;
class TestClassA : public TestClass
{
public:
    void m_print();
};
REGISTER(TestClassA);
#endif

TestClassA.cpp

#include <TestClassA.h>
#include <iostream>
using namespace std;
void TestClassA::m_print(){
        cout<<"hello TestClassA...."<<endl;
}

TestClassB.h

#ifndef __TestClassB__
#define __TestClassB__
#include <TestClass.h>
#include <reflection.h>
#include <iostream>
//TestClassB {
using namespace std;
class TestClassB : public TestClass{

public:
    void m_print();
};
REGISTER(TestClassB);
#endif

TestClassB.cpp

#include <TestClassB.h>
#include <iostream>
using namespace std;
void TestClassB::m_print(){
        cout<<"hello TestClassB....i am changed...."<<endl;
}

编译TestClassA:

#in linux
g++ -std=c++11 -fpic -shared -o libclassa.so TestClassA.cpp -I.
#in mac:
g++ -std=c++11 -fpic -shared -o libclassa.so TestClassA.cpp -I. -L. -lreflection

编译TestClassB

#in linux
g++ -std=c++11 -fpic -shared -o libclassb.so TestClassB.cpp -I.
#in mac
g++ -std=c++11 -fpic -shared -o libclassb.so TestClassB.cpp -I. -L. -lreflection

编译主程序:

g++ -g -std=c++11   main.cpp -I. -L. -lclassa -lclassb -lreflection -o main

注意:如果so库找不到
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

测试

#!/bin/sh
./main TestClassA
./main TestClassB

结果:

[root@4c8g210129 demo2]# ./test.sh
argv 1: TestClassA
hello TestClassA....
argv 1: TestClassB
hello TestClassB....i am changed....
[root@4c8g210129 demo2]#

每次修改TestClassA.cpp或者TestClassB.cpp
的时候不用修改main.cpp

标签:__,反射,TestClassB,demo,void,c++,className,include,ClassFactory
来源: https://blog.csdn.net/leafrenchleaf/article/details/115432428

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有