#include <factory.h>
Public Member Functions | |
Factory () | |
Default constructor. | |
virtual | ~Factory () |
Destructor. |
A class factory (or virtual constructor) is a class that can create instances of another class. Factory is a base class for such factories. When declaring an Array, Vec or Mat, a factory can be passed as an (optional) constructor argument:
// Declare a Vec<type> with size=10 and factory=DEFAULT_FACTORY Vec<type> a(10); // Declare a Vec<type> with size=10 and factory=f Factory f; Vec<type> b(10, f);
By default, the factory (DEFAULT_FACTORY
and f
in the above examples) is not used at all! However, by overloading a help function called create_elements we can force Array/Vec/Mat to use the factory for element creation (instead of using the default constructor for the element type).
class My_Type { public: // Default constructor My_Type() : data(0) {} // Constructor My_Type(int d) : data(d) {} . . . protected: int data; }; class My_Factory : public Factory { public: // Constructor explicit My_Factory(int d) : init_data(d) {} // Destructor virtual ~My_Factory() {} // Create an n-length array of My_Type virtual void create(My_Type* &ptr, int n) const {ptr = new My_Type[n](init_data);} protected: int init_data; }; // Create an n-length array of My_Type using My_Factory f template<> void create_elements<My_Type>(My_Type* &ptr, int n, const Factory &f) { if (const My_Factory *my_factory_ptr = dynamic_cast<const My_Factory*>(&f)) { // Yes, f seems to be a My_Factory. Now call the My_Factory::create method my_factory_ptr->create(ptr, n); } else { // No, f does not seem to be a My_Factory. As a fallback solution, // assume that f is DEFAULT_FACTORY and use the default constructor ptr = new My_Type[n]; } }
Now,
// Declare a My_Factory for init_data = 123 My_Factory my123_factory(123); // Declare a Vec<My_Type> with size 10 that uses My_Type() for element creation Vec<My_Type> v1(10); // Declare a Vec<My_Type> with size 10 that uses My_Type(123) for element creation Vec<My_Type> v1(10, my123_factory);
For a more interesting example, see Fix_Factory.