MetaObject.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. //
  2. // MetaObject.h
  3. //
  4. // $Id: //poco/1.4/Foundation/include/Poco/MetaObject.h#1 $
  5. //
  6. // Library: Foundation
  7. // Package: SharedLibrary
  8. // Module: ClassLoader
  9. //
  10. // Definition of the MetaObject class.
  11. //
  12. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  13. // and Contributors.
  14. //
  15. // SPDX-License-Identifier: BSL-1.0
  16. //
  17. #ifndef Foundation_MetaObject_INCLUDED
  18. #define Foundation_MetaObject_INCLUDED
  19. #include "Poco/Foundation.h"
  20. #include "Poco/Exception.h"
  21. #include "Poco/SingletonHolder.h"
  22. #include <set>
  23. namespace Poco {
  24. template <class B>
  25. class AbstractMetaObject
  26. /// A MetaObject stores some information
  27. /// about a C++ class. The MetaObject class
  28. /// is used by the Manifest class.
  29. /// AbstractMetaObject is a common base class
  30. /// for all MetaObject in a rooted class hierarchy.
  31. /// A MetaObject can also be used as an object
  32. /// factory for its class.
  33. {
  34. public:
  35. AbstractMetaObject(const char* name): _name(name)
  36. {
  37. }
  38. virtual ~AbstractMetaObject()
  39. {
  40. for (typename ObjectSet::iterator it = _deleteSet.begin(); it != _deleteSet.end(); ++it)
  41. {
  42. delete *it;
  43. }
  44. }
  45. const char* name() const
  46. {
  47. return _name;
  48. }
  49. virtual B* create() const = 0;
  50. /// Create a new instance of a class.
  51. /// Cannot be used for singletons.
  52. virtual B& instance() const = 0;
  53. /// Returns a reference to the only instance
  54. /// of the class. Used for singletons only.
  55. virtual bool canCreate() const = 0;
  56. /// Returns true iff the create method can be used
  57. /// to create instances of the class.
  58. /// Returns false if the class is a singleton.
  59. virtual void destroy(B* pObject) const
  60. /// If pObject was owned by meta object, the
  61. /// ownership of the deleted object is removed
  62. /// and the object is deleted.
  63. {
  64. typename ObjectSet::iterator it = _deleteSet.find(pObject);
  65. if (it != _deleteSet.end())
  66. {
  67. _deleteSet.erase(pObject);
  68. delete pObject;
  69. }
  70. }
  71. B* autoDelete(B* pObject) const
  72. /// Give ownership of pObject to the meta object.
  73. /// The meta object will delete all objects it owns
  74. /// when it is destroyed.
  75. ///
  76. /// Returns pObject.
  77. {
  78. if (this->canCreate()) // guard against singleton
  79. {
  80. poco_check_ptr (pObject);
  81. _deleteSet.insert(pObject);
  82. }
  83. else throw InvalidAccessException("Cannot take ownership of", this->name());
  84. return pObject;
  85. }
  86. virtual bool isAutoDelete(B* pObject) const
  87. /// Returns true if the object is owned
  88. /// by meta object.
  89. ///
  90. /// Overloaded in MetaSingleton - returns true
  91. /// if the class is a singleton.
  92. {
  93. return _deleteSet.find(pObject) != _deleteSet.end();
  94. }
  95. private:
  96. AbstractMetaObject();
  97. AbstractMetaObject(const AbstractMetaObject&);
  98. AbstractMetaObject& operator = (const AbstractMetaObject&);
  99. typedef std::set<B*> ObjectSet;
  100. const char* _name;
  101. mutable ObjectSet _deleteSet;
  102. };
  103. template <class C, class B>
  104. class MetaObject: public AbstractMetaObject<B>
  105. /// A MetaObject stores some information
  106. /// about a C++ class. The MetaObject class
  107. /// is used by the Manifest class.
  108. /// A MetaObject can also be used as an object
  109. /// factory for its class.
  110. {
  111. public:
  112. MetaObject(const char* name): AbstractMetaObject<B>(name)
  113. {
  114. }
  115. ~MetaObject()
  116. {
  117. }
  118. B* create() const
  119. {
  120. return new C;
  121. }
  122. B& instance() const
  123. {
  124. throw InvalidAccessException("Not a singleton. Use create() to create instances of", this->name());
  125. }
  126. bool canCreate() const
  127. {
  128. return true;
  129. }
  130. };
  131. template <class C, class B>
  132. class MetaSingleton: public AbstractMetaObject<B>
  133. /// A SingletonMetaObject disables the create() method
  134. /// and instead offers an instance() method to access
  135. /// the single instance of its class.
  136. {
  137. public:
  138. MetaSingleton(const char* name): AbstractMetaObject<B>(name)
  139. {
  140. }
  141. ~MetaSingleton()
  142. {
  143. }
  144. B* create() const
  145. {
  146. throw InvalidAccessException("Cannot create instances of a singleton class. Use instance() to obtain a", this->name());
  147. }
  148. bool canCreate() const
  149. {
  150. return false;
  151. }
  152. B& instance() const
  153. {
  154. return *_object.get();
  155. }
  156. bool isAutoDelete(B* /*pObject*/) const
  157. {
  158. return true;
  159. }
  160. private:
  161. mutable SingletonHolder<C> _object;
  162. };
  163. } // namespace Poco
  164. #endif // Foundation_MetaObject_INCLUDED