This repository implements a simple factory-pattern and a singleton in a library called factory
.
A singleton can be used for creating a single instance of a concrete factory.
The singleton doesn't have constructors, so objects of this type cannot be created. Intended use
is calling the static function Instance()
that returns a reference to a static object of type
<T>
, e.g. Singleton<Object>::Instance()
. An explicit instantiation of the Singleton template
must be exported from the library using __declspec(dllexport)
in Visual C++, otherwise the
the returned static-object is not truly 'singular' as each compilation unit will have its own
static-object.
This repository implements a factory-pattern template that can be instantiated to create objects
that share a base-class. Creator-functions, that create the actual objects identified by a type id,
are registered in a std::map
inside a concrete factory-object. Functionality of the factory-pattern
is showcased using an interface called IObject
, and two object-classes called Object1
and Object2
that implement the interface. The factory object registers two creator functions in object.cpp
:
bool b1 = Singleton<ObjectFactory>::Instance().registercreator(object_type::OBJECT1, &object1_creator_fcn);
bool b2 = Singleton<ObjectFactory>::Instance().registercreator(object_type::OBJECT2, &object2_creator_fcn);
In the main.cpp
we create concrete objects of type object_type::OBJECT1
and object_type::OBJECT2
as follows:
object_ptr obj1, obj2;
obj1 = Singleton<ObjectFactory>::Instance().createobject(object_type::OBJECT1);
obj2 = Singleton<ObjectFactory>::Instance().createobject(object_type::OBJECT2);
When the factory
library is loaded, ObjectFactory
registers the
creator functions, and these can be used for generating objects of type Object1
and Object2
.
Functionality has been tested using both g++ version 9.4.0 and Visual Studio 2019.
An executable called main
links against the factory
library, and creates an object of Object1
type and an
object of Object2
type using a factory singleton-object from the factory
. After this types of each of the objects are
printed to the screen.
In Visual C++ we need to export/import the instance of Singleton<ObjectFactory>
, explicitly instantiated in object.cpp, so
that this instance is used in the executable (main). If we don't do this, and call Singleton<ObjectFactory>::Instance()
from the main,
the ObjectFactory
in the main
and the factory
library are different, and the instance in the main
won't have any creator-functions registered.
In order to fix this problem in Visual C++, the explicitly instantiated Singleton template for the FactoryObject
must be exported/imported as
static-objects are unique only within a compilation unit:
template class FACTORY_EXPORT Singleton< Factory<object_ptr, object_id, createobject_fcn> >;
In dll_support.hpp
we have the following macros for exporting and importing definitions:
#if defined(_WIN32) && defined(FACTORY_DLL)
# ifdef FACTORY_BUILD
// Compiling a Windows DLL
# define FACTORY_EXPORT __declspec(dllexport)
# else
// Using a Windows DLL
# define FACTORY_EXPORT __declspec(dllimport)
# endif
// Windows or Linux static library, or Linux so
#else
# define FACTORY_EXPORT
#endif
This is not required in g++ as the symbols from the factory
are exported by default.
If you want to incorporate this library into your CMAKE-based project, you can use CMAKE's FetchContant in your build scripts as follows:
FetchContent_Declare(
factory
GIT_REPOSITORY https://github.com/JarnoRalli/factory-pattern
GIT_TAG v2.0.0)
FetchContent_MakeAvailable(factory)
target_link_library(<MY-TARGET> factory::factory)