MetaObject.h 4.0 KB

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