Мы пытаемся преобразовать наш код в библиотеку, чтобы обеспечить некоторый интерфейс с другими кодами. В коде мы часто используем фабрику объектов, основанную на одноэлементном шаблоне, в котором объекты объявляются с помощью макросов, реализованных в следующем порядке.
Наша проблема в том, что когда мы компилируем весь код в виде библиотеки, объекты больше не регистрируются на фабрике и не могут быть созданы при выполнении. Есть ли у вас какие-либо предложения? Примечательно, что что-то должно быть сделано внешним? Должен признаться, я достиг своих пределов ...
Большое спасибо!
Марк
template<typename AClass> class Factory
{
public :
//! typedef for function creating object by the Factory
typedef AClass*(*CreateFunc)();
bool Register(const std::string& id,
CreateFunc creator)
{
return _associations.insert(typename AssocMap::value_type(id, creator)).second;
}
bool Unregister(const std::string& id)
{ return _associations.erase(id) == 1; }
AClass* CreateObject(const std::string& id)
{
typename AssocMap::const_iterator i=_associations.find(id);
if(i!= _associations.end())
return (i->second)();
else
{
std::cerr << "Unknown Type in object factory : " << id << std::endl;
exit(-1);
}
}
AClass* CreateObjectIfAvailable(const std::string& id)
{
typename AssocMap::const_iterator i=_associations.find(id);
return (i!= _associations.end() ? (i->second)() : NULL);
}
static Factory & Instance()
{
static Factory obj;
return obj;
}
private:
//! AssocMap typedef used for map establishing correspondance between CL and std::strings
typedef std::map<std::string,CreateFunc> AssocMap;
// Singleton implies creation/destruction entirely private
Factory():_associations(std::map<std::string,CreateFunc>()) {}
//! Factory declared private to avoid bad surprises
Factory(const Factory&);
//!operator= declared private to avoid bad surprises
Factory& operator=(const Factory&);
~Factory() {}
//! associations_ contains the correspondance between std::strings and objects
AssocMap _associations;
};
#define DECLARE_CONSTITUTIVE_LAW(CLASS_NAME,KEYWORD) \
namespace { \
AbstractConstitutiveLaws* creator(){ return new (CLASS_NAME);} \
const std::string kwords(KEYWORD); \
const bool registered = Factory<AbstractConstitutiveLaws>::Instance().Register(kwords,creator); \
}