factory.cpp
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:9k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* factory.cpp - implements an object factory */
  2. /* Copyright 1993-1998 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01a,05oct98,sn   wrote
  7. */
  8. /*
  9. DESCRIPTION
  10. We implement an "object factory". The first step is to give
  11. classes human-readable names by registering them with a 
  12. "global class registry". Then objects of a named type may be 
  13. created and registered with an "object registry". 
  14. This gives us an opportunity to exercise various C++ features:
  15. * Standard Template Library
  16.     A "map" is used as the basis for the various registries.
  17. * User defined templates
  18.     The class registry and object registry are both based on a 
  19.     generic registry type.
  20. * Run Time Type Checking
  21.     We provide a function to determine the type of a registered 
  22.     object using "dynamic_cast".
  23. * Exception Handling
  24.     If we attempt to cast to the "wrong" type we have to handle a 
  25.     C++ exception.
  26. We provide a C interface to facilitate easy testing from the Wind Shell.
  27. Here is an example test run (you can run this whole test through the function
  28. testFactory()):
  29. -> classRegistryShow
  30. Showing Class Registry ...
  31. Name  Address
  32. =========================================================
  33. blue_t  0x6b1c7a0
  34. green_t 0x6b1c790
  35. red_t  0x6b1c7b0
  36. -> objectRegistryShow
  37. Showing Object Registry ...
  38. Name  Address
  39. =========================================================
  40. -> objectCreate "green_t", "bob"
  41. Creating an object called 'bob' of type 'green_t'
  42. -> objectCreate "red_t", "bill"
  43. Creating an object called 'bill' of type 'red_t'
  44. -> objectRegistryShow
  45. Showing Object Registry ...
  46. Name  Address
  47. =========================================================
  48. bill  0x6b1abf8
  49. bob  0x6b1ac18
  50. -> objectTypeShowByName "bob"
  51. Looking up object 'bob'
  52. Attempting to ascertain type of object at 0x6b1ac18
  53. Attempting a dynamic_cast to red_t ...
  54. dynamic_cast threw an exception ... caught here!
  55. Attempting a dynamic_cast to blue_t ...
  56. dynamic_cast threw an exception ... caught here!
  57. Attempting a dynamic_cast to green_t ...
  58. Cast to green_t succeeded!
  59. green.
  60. */
  61. /* includes */
  62. #include "factory.h"
  63. /* locals */
  64. /* pointer to the global class registry */
  65. LOCAL class_registry_t* pClassRegistry;
  66. /* pointer to the global object registry */ 
  67. LOCAL object_registry_t* pObjectRegistry;
  68. /******************************************************************************
  69. *
  70. * testFactory - an example test run
  71. *
  72. */
  73. void testFactory ()
  74. {
  75.     cout << "classRegistryShow ()" << endl;
  76.     classRegistryShow ();
  77.     cout << "objectRegistryShow ()" << endl;
  78.     objectRegistryShow ();
  79.     cout << "objectCreate ("green_t", "bob")" << endl;
  80.     objectCreate ("green_t", "bob");
  81.     cout << "objectCreate ("red_t", "bill")" << endl;
  82.     objectCreate ("red_t", "bill");
  83.     cout << "objectRegistryShow ()" << endl;
  84.     objectRegistryShow ();
  85.     cout << "objectTypeShowByName ("bob")" << endl;
  86.     objectTypeShowByName ("bob");
  87. }
  88. /******************************************************************************
  89. *
  90. * class_registry_t::create - create an object of type className
  91. *
  92. * Look up 'className' in this registry. If it exists then
  93. * create an object of this type by using the registered class factory;
  94. * otherwise return NULL.  
  95. *
  96. * RETURNS : pointer to new object of type className or NULL.
  97. */
  98. object_t* class_registry_t::create 
  99.     (
  100.     string className
  101.     ) 
  102.     { 
  103.     object_factory_t* pFactory = lookup (className);
  104.     if (pFactory != NULL)
  105.         {
  106.         return lookup (className)-> create (); 
  107.         }
  108.     else
  109.         {
  110.         cout << "No such class in Class Registry. " << endl;
  111.         return NULL;
  112.         }
  113.     }
  114. /******************************************************************************
  115. *
  116. * classRegistryGet - get a reference to the global class registry
  117. * Create and populate a new class registry if necessary.
  118. *
  119. * RETURNS : a reference to the global class registry
  120. */
  121. LOCAL class_registry_t& classRegistryGet ()
  122.     {
  123.     if (pClassRegistry == NULL)
  124.         {
  125.         pClassRegistry = new class_registry_t;
  126.         pClassRegistry -> insert ("red_t", new red_factory_t);
  127.         pClassRegistry -> insert ("blue_t", new blue_factory_t);
  128.         pClassRegistry -> insert ("green_t", new green_factory_t);
  129.         }
  130.     return *pClassRegistry;
  131.     }
  132. /******************************************************************************
  133. *
  134. * objectRegistryGet - get a reference to the global object registry
  135. *
  136. * Create a new object registry if necessary.
  137. *
  138. * RETURNS : a reference to the global object registry
  139. */
  140. LOCAL object_registry_t& objectRegistryGet ()
  141.     {
  142.     if (pObjectRegistry == NULL)
  143.         {
  144.         pObjectRegistry = new object_registry_t;
  145.         }
  146.     return *pObjectRegistry;
  147.     }
  148. /******************************************************************************
  149. *
  150. * objectCreate - create an object of a given type
  151. *
  152. * Use the class factory registered in the global class registry
  153. * under 'className' to create a new object. Register this object
  154. * in the global object registry under 'object name'.
  155. *
  156. * RETURNS : object of type className
  157. */
  158. object_t* objectCreate 
  159.     (
  160.     char* className, 
  161.     char* objectName
  162.     )
  163.     {
  164.     cout << "Creating an object called '" << objectName << "'" 
  165.          << " of type '" << className << "'" << endl;
  166.     object_t* pObject = classRegistryGet().create (className);
  167.     if (pObject != NULL)
  168.         {
  169.         objectRegistryGet().insert(objectName, pObject);
  170.         }
  171.     else
  172.         {
  173.         cout << "Could not create object. Sorry. " << endl;
  174.         }
  175.     return pObject;
  176.     }
  177. /******************************************************************************
  178. *
  179. * isRed   
  180. * isBlue   - is anObject a reference to an object of the specified type?
  181. * isGreen 
  182. *
  183. * Try a dynamic_cast. If this succeeds then return TRUE. If it fails
  184. * then catch the resulting exception and return FALSE.
  185. *
  186. * RETURNS : TRUE or FALSE
  187. */
  188. /* isRed */
  189. LOCAL BOOL isRed (object_t& anObject)
  190.     {
  191.     try
  192.         {
  193. cout << "Attempting a dynamic_cast to red_t ..." << endl;
  194.         dynamic_cast<red_t&> (anObject);
  195.         cout << "Cast to red_t succeeded!" << endl;
  196.         return TRUE;
  197.         }
  198.     catch (exception)
  199.         {
  200.         cout << "dynamic_cast threw an exception ... caught here!" << endl;
  201.         return FALSE;
  202.         }    
  203.     }
  204. /* isBlue */
  205. LOCAL BOOL isBlue (object_t& anObject)
  206.     {
  207.     try
  208.         {
  209. cout << "Attempting a dynamic_cast to blue_t ..." << endl;
  210.         dynamic_cast<blue_t&> (anObject);
  211.         cout << "Cast to blue_t succeeded!" << endl;
  212.         return TRUE;
  213.         }
  214.     catch (exception)
  215.         {
  216.         cout << "dynamic_cast threw an exception ... caught here!" << endl;
  217.         return FALSE;
  218.         }    
  219.     }
  220. /* isGreen */
  221. LOCAL BOOL isGreen (object_t& anObject)
  222.     {
  223.     try
  224.         {
  225. cout << "Attempting a dynamic_cast to green_t ..." << endl;
  226.         dynamic_cast<green_t&> (anObject);
  227.         cout << "Cast to green_t succeeded!" << endl;
  228.         return TRUE;
  229.         }
  230.     catch (exception)
  231.         {
  232.         cout << "dynamic_cast threw an exception ... caught here!" << endl;
  233.         return FALSE;
  234.         }    
  235.     }
  236. /******************************************************************************
  237. *
  238. * objectTypeShow - ascertain the type of an object
  239. *
  240. * Use dynamic type checking to determine the type of an object.
  241. *
  242. * RETURNS : N/A
  243. */
  244. LOCAL void objectTypeShow (object_t* pObject)
  245.     {
  246.     cout << "Attempting to ascertain type of object at " << "0x" << hex 
  247.          << (int) pObject << endl;
  248.     if (isRed (*pObject))
  249.         {
  250.         cout << "red." << endl;
  251.         }
  252.     else if (isBlue (*pObject))
  253.         {
  254.         cout << "blue." << endl;
  255.         }
  256.     else if (isGreen (*pObject))
  257.         {
  258.         cout << "green." << endl;
  259.         }
  260.     }
  261. /******************************************************************************
  262. *
  263. * objectTypeShowByName - ascertain the type of a registered object
  264. *
  265. * Lookup 'objectName' in the global object registry and 
  266. * print the type of the associated object.
  267. *
  268. * RETURNS : N/A
  269. */
  270. void objectTypeShowByName 
  271.     (
  272.     char* objectName
  273.     )
  274.     {
  275.     cout << "Looking up object '" << objectName << "'" << endl;
  276.     object_t *pObject = objectRegistryGet ().lookup (objectName);
  277.     if (pObject != NULL)
  278.         {
  279.         objectTypeShow (pObject);
  280.         }
  281.     else
  282.         {
  283.         cout << "No such object in the Object Registry." << endl;
  284.         }
  285.     }
  286. /******************************************************************************
  287. *
  288. * objectRegistryShow - show contents of global object registry
  289. *
  290. * RETURNS : N/A
  291. */
  292. void objectRegistryShow ()
  293.     {
  294.     cout << "Showing Object Registry ..." << endl;
  295.     objectRegistryGet ().list ();
  296.     }
  297. /******************************************************************************
  298. *
  299. * classRegistryShow - show contents of global class registry
  300. *
  301. * RETURNS : N/A
  302. */
  303. void classRegistryShow ()
  304.     {
  305.     cout << "Showing Class Registry ..." << endl;
  306.     classRegistryGet ().list ();
  307.     }