c++的反射的demo

c++的反射的demo

    • 一个基本例子
    • 把这个改造成:调用方不改,底层so可以改的方式

一个基本例子

reflection.cpp

// 工厂类的定义
#include 
#include 
#include 
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 
#include 
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 
#include 
#include 
#include 
// 工厂类的实现
// 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 
#include 
#include 
using namespace std;

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

#endif

主函数为

#include 
#include 
#include 
#include 
#include 
#include 
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 
#include 

具体的实现TestClassA.h为

#ifndef __TestClassA__
#define __TestClassA__
#include 
#include 
#include 
using namespace std;
class TestClassA : public TestClass
{
public:
    void m_print();
};
REGISTER(TestClassA);
#endif

TestClassA.cpp

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

TestClassB.h

#ifndef __TestClassB__
#define __TestClassB__
#include 
#include 
#include 
//TestClassB {
using namespace std;
class TestClassB : public TestClass{

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

TestClassB.cpp

#include 
#include 
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

你可能感兴趣的:(linux,c)