intelliproject logo

Location: Desktop development - C/C++    License: The Intelliproject Open License (IPOL)

Generic Derived Class Factory in C++

Posted by Mark Jundo P. Documento

A reusable C++ implementation of a factory for derived classes

Skill: Intermediate

Posted: 02/03/2009

Views: 2455

Rating: 5.00 /5

Popularity: 1.51

Sign Up to vote for this article

Introduction

The goal of this article is to create a reusable class based on the Abstract Factory Pattern though, for some reason I can't remember, I chose to name it DerivedClassFactory. The design of this factory should allow us to register classes without changing anything within the factory itself. Another goal is to create a factory where the id used to generate the classes can be customized using C++ templates. The class also offers run time type safety with the help of templates and the dynamic_cast operator. We will be using the STL container map to keep our registration information, since STL comes with any decent C++ compiler and it is after all, a C++ standard.

Design

The design of our factory has the following straightforward specifications:

  • Allow registration of classes
  • Should have a data type for holding the information about registered classes and their ids
  • Allow creation of registered classes through their ids

Based on this, we would have something like:

The registry member variable holds our registration entry. This is a std::map object with template the class parameter _ID_ as key and a pointer to ClassFactoryFunc as value types respectively. We have defined ClassFactoryFunc as a function that returns a dynamically created instance of our base class, which is the class template parameter _BASE_.

At the heart of the factory is a generic function that actually instantiates the derived class we intend to register.

This is a static function that will provide us with a ClassFactoryFunc pointer that we can store in our registry. Type safey is acheived by dynamic_casting the derived type pointer to our base class.

We now add the method to register a class:

To create or instantiate our registered classes we then use the following method:

which is just a matter of searching for the id we want in the registry and executing the function pointer that we stored earlier.

Using the Factory

To use our factory we need to instantiate it with the template parameters _ID_  and _BASE_ which is our id and base class types respectively:

To register classes we just use the registerClass function:

Or we could use the a macro that does just what the above code does:

To create an object:

Points of Interest

The extra delete in derivedClassFactoryFunc is a pain if you are dealing with large classes. But, it is necessary and should not happen if you write your code with forethought and care.

Conclusion

The Abstract Factory pattern is a common pattern in software engineering. Harnessing the power of templates in C++ allowed us to create a factory that is simple, type-safe, reusable and allows us to register classes without changing the factory class code itself.

License

This article, along with any associated source code and files, is licensed under The Intelliproject Open License (IPOL)

About the author

Mark Jundo P. Documento

Location: Philippines
Ocupation: Software Developer
Home page: http://uhaw-pa-sa-camel.blogspot.com/

Posted by Mark Jundo P. Documento at 02/03/2009 22:04
In the downloadable source code, DerivedClassFactory::create contains the following:
// . . .
if (registry.find(s) != registry.end())
obj = (registry.find(s)->second)();

This should be:
if (it != registry.end())
obj = (it->second)();

Sorry, will fix it later. :D
Posted by joseph xavier at 03/03/2009 10:51
I have been looking at implementing an Abstract Factory pattern for an analytics system my firm has been working on. This is a good intro to the pattern.
Have you had a look at PapaFactory

http://sourceforge.net/projects/papafactory

It comes with a very good tutorial on factories and design in C++. Maybe it will be of interest to you.

Joseph
Posted by Mark Jundo P. Documento at 19/03/2009 18:32
Hi Joseph. Thanks for the info. Will look it up! :D
Posted by Marc Teichtahl at 01/04/2010 02:30
it is possible to create objects of type other than Base ?

Sign up to post message on the article message board!