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)
#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();
};
#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;
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;
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();
};
#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;
#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