• C++ 根据对象名字创建对象


    base.hpp的代码: 

    #ifndef _H_DYNAMIC_H
    #define _H_DYNAMIC_H

    #include "Base.h"
    #include <iostream>
    #include <map>
    using namespace std;

    template<typename T> Base * createT() { return new T; }

    struct BaseFactory {
        typedef std::map<std::string, Base*(*)()> map_type;

        static Base * createInstance(std::string const& s) {
            map_type::iterator it = getMap()->find(s);
            if(it == getMap()->end())
                return 0;
            return it->second();
        }

        protected:
        static map_type * getMap() {
            if(!map) { map = new map_type; } 
            return map; 
        }

        public:
        static map_type * map;
    };

    template<typename T>
    struct DerivedRegister : BaseFactory { 
        DerivedRegister(std::string const& s) { 
            getMap()->insert(std::make_pair(s, &createT<T>));
            cout<<"add"<<endl;
        }
    };
    #define REGISTER_DEC_TYPE(NAME) static DerivedRegister<NAME> reg
    #define REGISTER_DEF_TYPE(NAME) DerivedRegister<NAME> NAME::reg(#NAME)

    #endif  

    Base.h的代码:

    #ifndef _H_BASE_H
    #define _H_BASE_H
    #include <iostream>
    using namespace std;

    class Base {
        string name;
    public:
        virtual void print();
        virtual ~Base();
    };

    #endif

    Base.cpp的代码: 

    #include "Base.h"

    Base::~Base(){
        cout<<"detructed"<<endl;
    }

    void Base::print(){
        cout<<"base"<<endl;

    } 

    derivedb.h的代码:

    #include "derivedb.hpp"
    DerivedRegister<DerivedB> DerivedB::reg("DerivedB");

    void DerivedB::print(){
        cout<<"derived"<<endl;

    } 

    derivedb.hpp的代码:

    #ifndef _H_DERIVEDB_H
    #define _H_DERIVEDB_H

    #include <iostream>
    #include "base.hpp"
    #include "Base.h"
    using namespace std;

    class DerivedB : public Base{
    private:
        static DerivedRegister<DerivedB> reg;
    public :
        void print();
    };

    #endif

    main的测试代码:

    #include "Animal.h"
    #include "Cat.h"
    #include <iostream>
    #include "base.hpp"
    #include <dlfcn.h>
    #include "derivedb.hpp"
    #include <map>
    using namespace std;

    BaseFactory::map_type * BaseFactory::map;
    class Base;

    void load(){
        void *handle = dlopen("./deriveb.so",RTLD_NOW|RTLD_GLOBAL);
        if(!handle)
        {
            std::cerr << dlerror() << std::endl;
            return;
        }
        else{
            cout<<"load OK"<<endl;
        }

        Base * bp = BaseFactory::createInstance("DerivedB");
        bp->print();
    }

    using namespace std;
    int main(int argc, char ** argv ){
        load();
        return 0;

    } 

    编译:

    g++ -fPIC -shared -o deriveb.so  derivedb.cpp  

    g++ -c Base.cpp 

    g++ -rdynamic -g -ldl  main.cpp Base.o

    这里有一个非常关键的地方,就是这个-rdynamic,如果不加这个选项,dlopen会包undifined symbol,参考:http://stackoverflow.com/questions/480617/dlopen-issue


  • 相关阅读:
    后端结对编程报告(2018.6.6)
    Burn Down Chart(2018.6.4~2018.6.10)
    C#多线程List的非线程安全性
    C#泛型参数多线程与复杂参数多线程
    Java学习之App开发公司手机端设想
    Java学习之SpringBoot整合SSM Demo
    Java学习之Mysql结构优化
    Java学习之Dubbo+ZooKeeper分布式服务Demo
    C# 面向切面编程--监控日志记录方案
    C# 通用类型转换方法
  • 原文地址:https://www.cnblogs.com/welkinwalker/p/2278394.html
Copyright © 2020-2023  润新知