Thursday, 15 May 2014

c++ - Instantiating classes by name with factory pattern -


Suppose I have a list of classes A, B, C, ... All the heirs to base .

I get the name of the class as a string from the user, and I want to instantiate the right square and give an indicator the base . How do you implement it?

I used a hash table with the name of the class as the key, and a function pointer for the function that gives the correct class immediately and Base * .

However, I think I might be able to use the factory pattern here and make it very easy, but I can not remember it well, so I would ask however for.

Here is a general implementation:

  template & lt; Class interface, square bit = std :: string & gt; Structure factory {typical insect key; Typedef std :: auto_ptr & lt; Interface & gt; type; Type Type (* Manufacturer) (); Bool defined (key const & key, creator v) {// define key - & gt; V relation, whether it is a new key to return. Return _registry.insert (typename registry :: value_type (key, v)). second; } (Key set and key) {typename registry: const_iterator i = _registry.find (key); If (i == _registry.end ()) {std :: invalid_argument (std :: string (__ PRETTY_FUNCTION__) + ": key is not registered"); } And come back to I- & gt; second (); } Template & lt; Class base, class real & gt; Fixed std :: auto_ptr & lt; Base & gt; Create_func () {return std :: auto_ptr & lt; Base & gt; (New real ()); } Private: typedef std :: map & lt; Key, Creator & gt; Registry; Registry _ Registry; };  

This is not to be the best in every circumstance, but it means that for the first time before implementing the type of functional type manually, the estimation should be more useful default. How to register each hierarchy is not mandatory by the factory, but you can mention the GF (it is simple, clear and very useful, and yes, in this case, with the macro, it prevents the underlying problems).

There is a factory here:

  struct basis {typedef :: factory & lt; Base & gt; Factory; Virtual ~ Base () {} Virtual At Answer () const = 0; Static Factory :: Type (Factory :: Main Treaty and Name) {back _factory.create (name); } Template & lt; Class uplift & gt; Static Zero Defined (Factory :: Main Treaty and Name) {bool new_key = _factory.define (name and factory :: template create_func & lt; base, executed & gt;); If (not new_key) {std :: logic_error (std :: string (__ PRETTY_FUNCTION__) + ": name is already registered"); }} Private: Static Factory _ Factor; }; Base :: Factory Base :: _ Factory; Structure A: Base {virtual et answer () const {returns 42; }}; Int main () {base :: defined & lt; A & gt; ("a"); Emphasis (base :: build ("a") -> answer () == 42); Return 0; }  

No comments:

Post a Comment