pfactory.h File Reference
`#include <ptlib.h>`
`#include <string>`
`#include <map>`
`#include <vector>`

Go to the source code of this file.

## Classes

class | PFactoryBase
| Base class for generic factories. More...
class | PFactoryBase::FactoryMap
class | PFactory< AbstractClass, KeyType >
| Template class for generic factories of an abstract class. More...
class | PFactory< AbstractClass, KeyType >::WorkerBase
class | PFactory< AbstractClass, KeyType >::Worker< ConcreteClass >

## Macros

#define | PFACTORY_CREATE(factory, ConcreteClass, ...)
| This macro is used to create a factory. More...
#define | PFACTORY_CREATE_SINGLETON(factory, ConcreteClass) PFACTORY_CREATE(factory, ConcreteClass, typeid(ConcreteClass).name(), true)
#define | PFACTORY_GET_SINGLETON(factory, ConcreteClass)
#define | PFACTORY_LOAD(ConcreteType)

## Typedefs

typedef std::string | PDefaultPFactoryKey
| These templates implement an Abstract Factory that allows creation of a class "factory" that can be used to create "concrete" instance that are descended from a abstract base class. More...

## Macro Definition Documentation

## PFACTORY_CREATE

#define PFACTORY_CREATE | ( |  | factory,
|  |  | ConcreteClass,
|  |  | ...
| ) |  |

Value:
namespace PFactoryLoader { \
int ConcreteClass##_link() { return 0; } \
factory::Worker<ConcreteClass> ConcreteClass##_instance(__VA_ARGS__); \
}

This macro is used to create a factory.

This is mainly used for factories that exist inside a library and works in conjunction with the PFACTORY_LOAD() macro.

When a factory is contained wholly within a single compilation module of a library, it is typical that a linker does not include ANY of the code in that module. To avoid this the header file that declares the abstract type should include a PFACTORY_LOAD() macro call for all concrete classes that are in the library. Then whan an application includes the abstract types header, it will force the load of all the possible concrete classes.

## PFACTORY_CREATE_SINGLETON

#define PFACTORY_CREATE_SINGLETON | ( |  | factory,
|  |  | ConcreteClass
| ) |  | PFACTORY_CREATE(factory, ConcreteClass, typeid(ConcreteClass).name(), true)

## PFACTORY_GET_SINGLETON

#define PFACTORY_GET_SINGLETON | ( |  | factory,
|  |  | ConcreteClass
| ) |  |

Value:
static ConcreteClass & GetInstance() { \
return *factory::CreateInstanceAs<ConcreteClass>(typeid(ConcreteClass).name()); \
}

## PFACTORY_LOAD

#define PFACTORY_LOAD | ( |  | ConcreteType | ) |

Value:
namespace PFactoryLoader { \
extern int ConcreteType##_link(); \
int const ConcreteType##_loader = ConcreteType##_link(); \
}

## Typedef Documentation

## PDefaultPFactoryKey

typedef std::string PDefaultPFactoryKey

These templates implement an Abstract Factory that allows creation of a class "factory" that can be used to create "concrete" instance that are descended from a abstract base class.

Given an abstract class A with a descendant concrete class B, the concrete class is registered by instantiating the PFactory template as follows:

      PFactory<A>::Worker<B> aFactory("B");

To instantiate an object of type B, use the following:

      A * b = PFactory<A>::CreateInstance("B");

A vector containing the names of all of the concrete classes for an abstract type can be obtained as follows:

      PFactory<A>::KeyList_T list = PFactory<A>::GetKeyList()

Note that these example assumes that the "key" type for the factory registration is of the default type PString. If a different key type is needed, then it is necessary to specify the key type:

      PFactory<C, unsigned>::Worker<D> aFactory(42);
      C * d = PFactory<C, unsigned>::CreateInstance(42);
      PFactory<C, unsigned>::KeyList_T list = PFactory<C, unsigned>::GetKeyList()

The factory functions also allow the creation of "singleton" factories that return a single instance for all calls to CreateInstance. This can be done by passing a "true" as a second paramater to the factory registration as shown below, which will cause a single instance to be minted upon the first call to CreateInstance, and then returned for all subsequent calls.

     PFactory<A>::Worker<E> eFactory("E", true);

It is also possible to manually set the instance in cases where the object needs to be created non-trivially.

The following types are defined as part of the PFactory template class:

    KeyList_T    a vector<> of the key type (usually std::string)
    Worker       an abstract factory for a specified concrete type
    KeyMap_T     a map<> that converts from the key type to the Worker instance
                 for each concrete type registered for a specific abstract type

As a side issue, note that the factory lists are all thread safe for addition, creation, and obtaining the key lists.