I have created a templated class where I would like to use the factory method. The templates should be explicitly defined to create objects of type int
, double
and bool
.
The factory has a checkIn registry mechanism through the use of the a static bool
.
The factory is defined as:
#ifndef Factory_H
#define Factory_H
#include <memory>
#include <map>
template<class Type>
class Base;
template<class Type>
class Factory
{
public:
using createObj = std::shared_ptr<Base<Type>>(*)();
static bool registerObj( const std::string& name, createObj type)
{
std::map< std::string, Factory::createObj >& registry = getRegistry();
if(registry.find(name) == registry.end())
{
registry[name] = type;
return true;
}
return false;
};
static std::shared_ptr<Base<Type>> New( const std::string& name)
{
auto it = getRegistry().find(name);
if (it == getRegistry().end()) {
return nullptr;
}
return it->second();
};
private:
static std::map<std::string, createObj>& getRegistry()
{
static std::map<std::string, Factory::createObj> registry;
return registry;
};
};
#endif
The base class is defined as:
#ifndef Base_H
#define Base_H
#include "factory.h"
template<class Type>
class Base: public Factory<Type>
{
public:
Base();
virtual void foo() = 0;
};
#endif
and implemented as:
#include "Base.h"
#include <iostream>
template <class Type>
Base<Type>::Base()
{}
// Explicit initalization
template class Base<int>;
template class Base<double>;
template class Base<bool>;
The derived class is defined as:
#ifndef Derived_H
#define Derived_H
#include "Base.h"
template<class Type>
class Derived: public Base<Type>
{
private:
static bool checkIn_;
static std::string className_;
public:
Derived();
virtual void foo() ;
static std::shared_ptr<Base<Type>> Create();
};
#endif
and implemented as:
#include "Derived.h"
template<class Type>
Derived<Type>::Derived()
{}
template<class Type>
std::string Derived<Type>::className_("Derived");
template<class Type>
std::shared_ptr<Base<Type>> Derived<Type>::Create()
{
return std::make_shared<Derived>();
}
template<class Type>
bool Derived<Type>::checkIn_ = Base<Type>::registerObj(Derived::className_, Derived::Create);
template<class Type>
void Derived<Type>::foo()
{
std::cout << typeid(Type).name() << std::endl;
}
// Explicit initalization
template class Derived<int>;
template class Derived<double>;
template class Derived<bool>;
The main.cpp is defined as:
#include<iostream>
#include "Derived.h"
#include "Base.h"
int main()
{
auto obj1 = Base<int>::New("Derived");
auto obj2 = Base<double>::New("Derived");
auto obj3 = Base<bool>::New("Derived");
obj1->foo();
obj2->foo();
obj3->foo();
return 0;
}
If I compile everything in one executable: g++ -g *.cpp -o main
. The factory method works.
If I try to compile it as a library; g++ -g -fPIC Base.cpp Derived.cpp -shared -o test.so
followed by g++ -g -o main main.cpp -I . -L. test.so
it no longer works. There is nothing in the registry... I would guess the static bool
is not doing its job.
How can I make this work?
Aucun commentaire:
Enregistrer un commentaire