I meet a strange problem. When I build my sources into a dynamic library, everything works fine, I can get expected result, but when I instead building into a static library, some wrong happens, yet I don't know why.
I want to implement a factory class that can create a specific class instance by its name in string format.
Minimum codes for demonstration:
factory.h
#ifndef _FACTORY_H
#define _FACTORY_H
#include
class SomeClass;
class Factory
{
typedef std::map<std::string, SomeClass*(*)()> mapType;
public:
static SomeClass * CreateInstance(const std::string &className);
protected:
static mapType * getMap();
private:
static mapType * _constructorMap;
};
template<typename T>
SomeClass * createSomeClass()
{
return new T;
}
template<typename T>
class FactoryRegister : Factory
{
public:
FactoryRegister(const std::string &name)
{
getMap()->insert(std::make_pair(name, &createSomeClass));
}
};
#define REGISTER_DEF_TYPE(NAME)
FactoryRegister NAME::regTbl(#NAME)
#define ADD_REGISTER_TABLE(NAME)
static FactoryRegister regTbl
#endif // _FACTORY_H
factory.cpp
#include
#include "factory.h"
Factory::mapType * Factory::_constructorMap = nullptr;
SomeClass * Factory::CreateInstance(const std::string &className)
{
mapType::iterator it = getMap()->find(className);
if(it == getMap()->end())
{
qWarning("Construct %s failed. Not find a construct in map.", className.c_str());
return nullptr;
}
return it->second();
}
Factory::mapType * Factory::getMap()
{
// never delete'ed. (exist until program termination)
// because we can't guarantee correct destruction order
if(!_constructorMap)
{
_constructorMap = new mapType;
}
return _constructorMap;
}
Until now, I can build factory source file into library, dynamic library or static library, say it libfactory.so
or libfactory.a
. And it will be linked with user codes, like SubClassA
, SubClassB
or any other sub-classes derived from SomeClass
:
// SubClassA.h
class SubClassA: public SomeClass
{
ADD_REGISTER_TABLE(SubClassA);
}
// SubClassA.cpp
REGISTER_DEF_TYPE(SubClassA);
Everything works fine when linking libfactory.so
, that is I can create SubClassA instances. But it won't work when linking libfactory.a
. As I know, the only difference is just the build library type.Below is the error print:
Construct SubClassA failed. Not find a construct in map
Besides, I found when linking against a static library, the mapType * getMap()
will always return different pointers, that really a weird thing.
Any ideas? Appreciate for that.