Main MRPT website > C++ reference for MRPT 1.5.7
CObject.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 #ifndef MRPT_COBJECT_H
10 #define MRPT_COBJECT_H
11 
12 #include <mrpt/system/memory.h>
14 #include <vector>
15 
16 #include <memory> // shared_ptr
17 
18 namespace mrpt
19 {
20  namespace utils
21  {
22  /** @name RTTI classes and functions
23  @{ */
24 
26 
27  /** A smart pointer to a CObject object
28  * \note Declared as a class instead of a typedef to avoid multiple defined symbols when linking dynamic libs.
29  * \ingroup mrpt_base_grp
30  */
32 
33  /** A structure that holds runtime class type information. Use CLASS_ID(<class_name>) to get a reference to the class_name's TRuntimeClassId descriptor.
34  * \ingroup mrpt_base_grp
35  */
37  {
38  const char* className;
39  /** Create an object of the related class, or NULL if it is virtual. */
40  mrpt::utils::CObject* (*ptrCreateObject)();
41  /** Gets the base class runtime id. */
42  const TRuntimeClassId* (*getBaseClass)();
43 
44  // Operations
45  mrpt::utils::CObject* createObject() const;
46  bool derivedFrom(const TRuntimeClassId* pBaseClass) const;
47  bool derivedFrom(const char* pBaseClass_name) const;
48 
49  };
50 
51  /** A wrapper class for a "TRuntimeClassId *", well-defined with respect to copy operators and constructors. \ingroup mrpt_base_grp
52  */
54 
55  /** Register a class into the MRPT internal list of "CSerializable" descendents.
56  * Used internally in the macros DEFINE_SERIALIZABLE, etc...
57  * \sa getAllRegisteredClasses
58  */
60 
61  /** Mostly for internal use within mrpt sources, to handle exceptional cases with multiple serialization names for backward compatibility (CMultiMetricMaps, CImage,...)
62  */
63  void BASE_IMPEXP registerClassCustomName(const char*customName, const TRuntimeClassId* pNewClass);
64 
65  /** Returns a list with all the classes registered in the system through mrpt::utils::registerClass.
66  * \sa registerClass, findRegisteredClass
67  */
68  std::vector<const mrpt::utils::TRuntimeClassId*> BASE_IMPEXP getAllRegisteredClasses();
69 
70  /** Like getAllRegisteredClasses(), but filters the list to only include children clases of a given base one.
71  * \sa getAllRegisteredClasses(), getAllRegisteredClassesChildrenOf() */
72  std::vector<const TRuntimeClassId*> BASE_IMPEXP getAllRegisteredClassesChildrenOf(const TRuntimeClassId* parent_id);
73 
74  /** Return info about a given class by its name, or NULL if the class is not registered
75  * \sa registerClass, getAllRegisteredClasses
76  */
78 
79 
80  /** Access to runtime class ID for a defined class name.
81  */
82  #define CLASS_ID(class_name) static_cast<const mrpt::utils::TRuntimeClassId*>(&class_name::class##class_name)
83 
84  /** Access to runtime class ID for a defined class name.
85  */
86  #define CLASS_ID_NAMESPACE(class_name,namespaceName) static_cast<const mrpt::utils::TRuntimeClassId*>(&namespaceName::class_name::class##class_name)
87 
88  /** Access to runtime class ID for a defined template class name.
89  */
90  #define CLASS_ID_TEMPLATE(class_name,T) static_cast<const mrpt::utils::TRuntimeClassId*>(& template <class T> class_name<T>::class##class_name)
91 
92  /** Evaluates to true if the given pointer to an object (derived from mrpt::utils::CSerializable) is of the given class. */
93  #define IS_CLASS( ptrObj, class_name ) ((ptrObj)->GetRuntimeClass()==CLASS_ID(class_name))
94 
95  /** Evaluates to true if the given pointer to an object (derived from mrpt::utils::CSerializable) is an instance of the given class or any of its derived classes. */
96  #define IS_DERIVED( ptrObj, class_name ) ((ptrObj)->GetRuntimeClass()->derivedFrom(CLASS_ID(class_name)))
97 
98  /** Auxiliary structure used for CObject-based RTTI. \ingroup mrpt_base_grp */
100  {
102  {
103  registerClass(pNewClass);
104  }
105  };
106 
107 
108  /** The virtual base class of all MRPT classes with a unified RTTI system.
109  * For each class named <code>CMyClass</code>, a new type named <code>CMyClassPtr</code> will be created as a smart pointer suitable for
110  * keeping referencing count smart pointers to objects of that class. By default the base class of all these smart pointers is CObjectPtr.
111  * \sa mrpt::utils::CSerializable \ingroup mrpt_base_grp
112  */
114  {
115  protected:
116  static mrpt::utils::TRuntimeClassId* _GetBaseClass();
117  public:
119 
120  /** Returns information about the class of an object in runtime. */
122  {
123  return CLASS_ID(CObject);
124  }
125 
126  /** Returns a copy of the object, indepently of its class. */
127  virtual CObject *duplicate() const = 0;
128 
129  /** Returns a copy of the object, indepently of its class, as a smart pointer (the newly created object will exist as long as any copy of this smart pointer). */
130  inline mrpt::utils::CObjectPtr duplicateGetSmartPtr() const;
131 
132  /** Cloning interface for smart pointers */
133  inline CObject *clone() const { return duplicate(); }
134 
135  virtual ~CObject() { }
136 
137  }; // End of class def.
138 
140  {
141  std::shared_ptr<CObject> m_ptr;
142  inline CObjectPtr() {}
143  explicit inline CObjectPtr(CObject* data) : m_ptr(data) { }
144  virtual CObject * pointer() { return m_ptr.get(); }
145  virtual CObject * get() { return m_ptr.get(); }
146  virtual const CObject * pointer() const { return m_ptr.get(); }
147  virtual const CObject * get() const { return m_ptr.get(); }
148  virtual CObject* operator ->(void) { return m_ptr.get(); }
149  virtual const CObject* operator ->(void) const { return m_ptr.get(); }
150  virtual CObject& operator *(void) { ASSERT_(m_ptr); return *m_ptr.get(); }
151  virtual const CObject& operator *(void) const { ASSERT_(m_ptr); return *m_ptr.get(); }
152  void clear() { m_ptr.reset(); }
153  bool operator !() const { return !m_ptr.operator bool(); }
154  operator bool() const { return m_ptr.operator bool(); }
155  void make_unique() { if (!m_ptr) return; m_ptr.reset(m_ptr.get()->clone()); }
156  bool present() const { return m_ptr.get()!=NULL; }
157  void set(CObject* p) { m_ptr.reset(p); }
158  void reset(CObject* p=NULL) { m_ptr.reset(p); }
159  void clear_unique() { m_ptr.reset(); }
160  };
161 
163 
164 
165  /** Just like DEFINE_MRPT_OBJECT but with DLL export/import linkage keywords. Note: The replication of macro arguments is to avoid errors with empty macro arguments */
166 #define DEFINE_MRPT_OBJECT_CUSTOM_LINKAGE(class_name, _STATIC_LINKAGE_, _VIRTUAL_LINKAGE_) \
167  /*! @name RTTI stuff */ \
168  /*! @{ */ \
169  protected: \
170  _STATIC_LINKAGE_ const mrpt::utils::TRuntimeClassId* _GetBaseClass(); \
171  _STATIC_LINKAGE_ mrpt::utils::CLASSINIT _init_##class_name;\
172  public: \
173  /*! A typedef for the associated smart pointer */ \
174  typedef class_name##Ptr Ptr; \
175  typedef class_name##Ptr ConstPtr; \
176  _STATIC_LINKAGE_ mrpt::utils::TRuntimeClassId class##class_name; \
177  _STATIC_LINKAGE_ const mrpt::utils::TRuntimeClassId *classinfo; \
178  _VIRTUAL_LINKAGE_ const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const MRPT_OVERRIDE; \
179  _STATIC_LINKAGE_ mrpt::utils::CObject* CreateObject(); \
180  _STATIC_LINKAGE_ class_name##Ptr Create(); \
181  _VIRTUAL_LINKAGE_ mrpt::utils::CObject *duplicate() const MRPT_OVERRIDE; \
182  /*! @} */ \
183  public: \
184  MRPT_MAKE_ALIGNED_OPERATOR_NEW \
185 
186  /** This declaration must be inserted in all CObject classes definition, within the class declaration. */
187 #define DEFINE_MRPT_OBJECT(class_name) \
188  DEFINE_MRPT_OBJECT_CUSTOM_LINKAGE(class_name, static /*none*/, virtual /*none*/)
189 
190  // This macro is a workaround to avoid possibly empty arguments to MACROS (when _LINKAGE_ evals to nothing...)
191 #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, _LINKAGE_ ) DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE2(class_name, base_name, _LINKAGE_ class_name)
192 #define DEFINE_MRPT_OBJECT_POST_CUSTOM_BASE_LINKAGE(class_name, base_name, _LINKAGE_ ) DEFINE_MRPT_OBJECT_POST_CUSTOM_BASE_LINKAGE2(class_name, base_name, _LINKAGE_ class_name)
193 
194 // Use this one when there is NO import/export macro:
195 #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_NO_LINKAGE(class_name, base_name) DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE2(class_name, base_name, class_name)
196 #define DEFINE_MRPT_OBJECT_POST_CUSTOM_BASE_NO_LINKAGE(class_name, base_name) DEFINE_MRPT_OBJECT_POST_CUSTOM_BASE_LINKAGE2(class_name, base_name, class_name)
197 
198 /** This declaration must be inserted in all CObject classes definition, before the class declaration. */
199 #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE2(class_name, base_name, class_name_LINKAGE_ ) \
200  class class_name_LINKAGE_; \
201  struct class_name_LINKAGE_##Ptr;
202 
203 /** This declaration must be inserted in all CObject classes definition, after the class declaration. */
204 #define DEFINE_MRPT_OBJECT_POST_CUSTOM_BASE_LINKAGE2(class_name, base_name, class_name_LINKAGE_ ) \
205  /*! The smart pointer type for the associated class */ \
206  struct class_name_LINKAGE_##Ptr : public base_name##Ptr \
207  { \
208  typedef class_name value_type; \
209  class_name##Ptr() { } \
210  explicit class_name##Ptr(class_name* p) : base_name##Ptr(p) { } \
211  class_name##Ptr(const mrpt::utils::CObjectPtr &p) { m_ptr = p.m_ptr; } \
212  /*! Return the internal plain C++ pointer */ \
213  class_name * pointer() { return dynamic_cast<class_name*>(m_ptr.get()); } \
214  class_name * get() { return dynamic_cast<class_name*>(m_ptr.get()); } \
215  /*! Return the internal plain C++ pointer (const) */ \
216  const class_name * pointer() const { return dynamic_cast<const class_name*>(m_ptr.get()); } \
217  const class_name * get() const { return dynamic_cast<const class_name*>(m_ptr.get()); } \
218  class_name* operator ->(void) { return dynamic_cast<class_name*>(m_ptr.get()); } \
219  const class_name* operator ->(void) const { return dynamic_cast<const class_name*>(m_ptr.get()); } \
220  class_name& operator *(void) { ASSERT_(m_ptr); return *dynamic_cast<class_name*>(m_ptr.get()); } \
221  const class_name& operator *(void) const { ASSERT_(m_ptr); return *dynamic_cast<const class_name*>(m_ptr.get()); } \
222  };
223 
224 
225  // This macro is a workaround to avoid possibly empty arguments to MACROS (when _LINKAGE_ evals to nothing...)
226  #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_LINKAGE(class_name,_LINKAGE_) DEFINE_MRPT_OBJECT_PRE_CUSTOM_LINKAGE2(class_name, _LINKAGE_ class_name)
227  #define DEFINE_MRPT_OBJECT_POST_CUSTOM_LINKAGE(class_name,_LINKAGE_) DEFINE_MRPT_OBJECT_POST_CUSTOM_LINKAGE2(class_name, _LINKAGE_ class_name)
228 
229  // Use this macro when there is NO export/import macro:
230  #define DEFINE_MRPT_OBJECT_PRE_NO_LINKAGE(class_name) DEFINE_MRPT_OBJECT_PRE_CUSTOM_LINKAGE2(class_name, class_name)
231  #define DEFINE_MRPT_OBJECT_POST_NO_LINKAGE(class_name) DEFINE_MRPT_OBJECT_POST_CUSTOM_LINKAGE2(class_name, class_name)
232 
233  // This one is almost identical to the one above, but without a member:
234  /** This declaration must be inserted in all CObject classes definition, before the class declaration. */
235  #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_LINKAGE2(class_name,class_name_LINKAGE_) \
236  struct class_name_LINKAGE_##Ptr;
237 
238  /** This declaration must be inserted in all CObject classes definition, after the class declaration. */
239  #define DEFINE_MRPT_OBJECT_POST_CUSTOM_LINKAGE2(class_name,class_name_LINKAGE_) \
240  /*! The smart pointer type for the associated class */ \
241  struct class_name_LINKAGE_##Ptr : public mrpt::utils::CObjectPtr \
242  { \
243  inline class_name##Ptr() : mrpt::utils::CObjectPtr(static_cast<mrpt::utils::CObject*>(NULL)) { } \
244  inline explicit class_name##Ptr(class_name* p) : mrpt::utils::CObjectPtr( static_cast<mrpt::utils::CObject*>(p) ) { } \
245  inline explicit class_name##Ptr(const mrpt::utils::CObjectPtr & p) : mrpt::utils::CObjectPtr(p) { ASSERTMSG_( p->GetRuntimeClass()->derivedFrom(#class_name),::mrpt::format("Wrong typecasting of smart pointers: %s -> %s",p->GetRuntimeClass()->className, #class_name) ) } \
246  /*! Return the internal plain C++ pointer */ \
247  inline class_name * pointer() { return dynamic_cast<class_name*>(mrpt::utils::CObjectPtr::pointer()); } \
248  /*! Return the internal plain C++ pointer (const) */ \
249  inline const class_name * pointer() const { return dynamic_cast<const class_name*>(mrpt::utils::CObjectPtr::pointer()); } \
250  inline class_name* operator ->(void) { return dynamic_cast<class_name*>( mrpt::utils::CObjectPtr::operator ->() ); } \
251  inline const class_name* operator ->(void) const { return dynamic_cast<const class_name*>( mrpt::utils::CObjectPtr::operator ->() ); } \
252  inline class_name& operator *(void) { return *dynamic_cast<class_name*>( mrpt::utils::CObjectPtr::operator ->() ); } \
253  inline const class_name& operator *(void) const { return *dynamic_cast<const class_name*>( mrpt::utils::CObjectPtr::operator ->() ); } \
254  };
255 
256  /** This declaration must be inserted in all CObject classes definition, before the class declaration.
257  */
258  #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE(class_name, base_name) \
259  DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, BASE_IMPEXP )
260 
261  /** This declaration must be inserted in all CObject classes definition, before the class declaration.
262  */
263  #define DEFINE_MRPT_OBJECT_PRE(class_name) DEFINE_MRPT_OBJECT_PRE_CUSTOM_LINKAGE(class_name, BASE_IMPEXP ) // This macro is valid for classes within mrpt-base only.
264  #define DEFINE_MRPT_OBJECT_POST(class_name) DEFINE_MRPT_OBJECT_POST_CUSTOM_LINKAGE(class_name, BASE_IMPEXP ) // This macro is valid for classes within mrpt-base only.
265 
266  /** This must be inserted in all CObject classes implementation files
267  */
268  #define IMPLEMENTS_MRPT_OBJECT(class_name, base,NameSpace) \
269  mrpt::utils::CObject* NameSpace::class_name::CreateObject() \
270  { return static_cast<mrpt::utils::CObject*>( new NameSpace::class_name ); } \
271  NameSpace::class_name##Ptr NameSpace::class_name::Create() \
272  { return NameSpace::class_name##Ptr( new NameSpace::class_name ); } \
273  const mrpt::utils::TRuntimeClassId* NameSpace::class_name::_GetBaseClass() \
274  { return CLASS_ID(base); } \
275  mrpt::utils::TRuntimeClassId NameSpace::class_name::class##class_name = { \
276  #class_name, NameSpace::class_name::CreateObject, &class_name::_GetBaseClass }; \
277  const mrpt::utils::TRuntimeClassId *NameSpace::class_name::classinfo = & NameSpace::class_name::class##class_name; \
278  const mrpt::utils::TRuntimeClassId* NameSpace::class_name::GetRuntimeClass() const \
279  { return CLASS_ID_NAMESPACE(class_name,NameSpace); } \
280  mrpt::utils::CLASSINIT NameSpace::class_name::_init_##class_name(CLASS_ID(base)); \
281  mrpt::utils::CObject * NameSpace::class_name::duplicate() const \
282  { return static_cast<mrpt::utils::CObject*>( new NameSpace::class_name(*this) ); }
283 
284 
285  /** This declaration must be inserted in virtual CSerializable classes definition:
286  */
287  #define DEFINE_VIRTUAL_MRPT_OBJECT(class_name) \
288  /*! @name RTTI stuff */ \
289  /*! @{ */ \
290  protected: \
291  static const mrpt::utils::TRuntimeClassId* _GetBaseClass(); \
292  public: \
293  static const mrpt::utils::TRuntimeClassId class##class_name; \
294  virtual const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const MRPT_OVERRIDE; \
295  friend class mrpt::utils::CStream; \
296  typedef class_name##Ptr Ptr; \
297  typedef class_name##Ptr ConstPtr; \
298  /*! @} */ \
299 
300  /** This must be inserted as implementation of some required members for
301  * virtual CSerializable classes:
302  */
303  #define IMPLEMENTS_VIRTUAL_MRPT_OBJECT(class_name, base_class_name,NameSpace) \
304  const mrpt::utils::TRuntimeClassId* class_name::_GetBaseClass() \
305  { return CLASS_ID(base_class_name); } \
306  const mrpt::utils::TRuntimeClassId class_name::class##class_name = { \
307  #class_name, NULL, &class_name::_GetBaseClass }; \
308  const mrpt::utils::TRuntimeClassId* class_name::GetRuntimeClass() const \
309  { return CLASS_ID(class_name); }
310 
311  /** @} */ // end of RTTI
312 
313  /** Register all pending classes - to be called just before de-serializing an object, for example.
314  * After calling this method, pending_class_registers_modified is set to false until pending_class_registers() is invoked.
315  */
317 
318  } // End of namespace
319 
320 /** Converts a smart pointer Base::Ptr to Derived::Ptr, in a way compatible
321 * with MRPT >=1.5.4 and MRPT 2.x series.
322 * \ingroup mrpt_base_grp
323 */
324 template <typename CAST_TO>
325 struct ptr_cast
326 {
327  template <typename CAST_FROM_PTR>
328  static typename CAST_TO::Ptr from(const CAST_FROM_PTR &ptr)
329  {
330  return typename CAST_TO::Ptr(ptr);
331  }
332 };
333 
334 } // End of namespace
335 
336 #endif
Auxiliary structure used for CObject-based RTTI.
Definition: CObject.h:99
void BASE_IMPEXP registerAllPendingClasses()
Register all pending classes - to be called just before de-serializing an object, for example...
safe_ptr< TRuntimeClassId > TRuntimeClassIdPtr
A wrapper class for a "TRuntimeClassId *", well-defined with respect to copy operators and constructo...
Definition: CObject.h:53
std::vector< const mrpt::utils::TRuntimeClassId * > BASE_IMPEXP getAllRegisteredClasses()
Returns a list with all the classes registered in the system through mrpt::utils::registerClass.
virtual const mrpt::utils::TRuntimeClassId * GetRuntimeClass() const
Returns information about the class of an object in runtime.
Definition: CObject.h:121
Converts a smart pointer Base::Ptr to Derived::Ptr, in a way compatible with MRPT >=1...
Definition: CObject.h:325
void BASE_IMPEXP registerClassCustomName(const char *customName, const TRuntimeClassId *pNewClass)
Mostly for internal use within mrpt sources, to handle exceptional cases with multiple serialization ...
const TRuntimeClassId BASE_IMPEXP * findRegisteredClass(const std::string &className)
Return info about a given class by its name, or NULL if the class is not registered.
void reset(CObject *p=NULL)
Definition: CObject.h:158
virtual ~CObject()
Definition: CObject.h:135
GLsizei const GLchar ** string
Definition: glext.h:3919
mrpt::utils::CObjectPtr duplicateGetSmartPtr() const
Returns a copy of the object, indepently of its class, as a smart pointer (the newly created object w...
Definition: CObject.h:162
std::shared_ptr< CObject > m_ptr
Definition: CObject.h:141
static const mrpt::utils::TRuntimeClassId classCObject
Definition: CObject.h:118
#define CLASS_ID(class_name)
Access to runtime class ID for a defined class name.
Definition: CObject.h:82
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
virtual const CObject * pointer() const
Definition: CObject.h:146
Eigen::MatrixBase< Derived >::PlainObject operator!(const Eigen::MatrixBase< Derived > &m)
Unary inversion operator.
Definition: ops_matrices.h:38
virtual CObject * pointer()
Definition: CObject.h:144
#define ASSERT_(f)
static CAST_TO::Ptr from(const CAST_FROM_PTR &ptr)
Definition: CObject.h:328
bool present() const
Definition: CObject.h:156
CLASSINIT(const mrpt::utils::TRuntimeClassId *pNewClass)
Definition: CObject.h:101
void BASE_IMPEXP registerClass(const mrpt::utils::TRuntimeClassId *pNewClass)
Register a class into the MRPT internal list of "CSerializable" descendents.
A structure that holds runtime class type information.
Definition: CObject.h:36
The virtual base class of all MRPT classes with a unified RTTI system.
Definition: CObject.h:113
struct BASE_IMPEXP CObjectPtr
A smart pointer to a CObject object.
Definition: CObject.h:31
const char * className
Definition: CObject.h:38
CObject * clone() const
Cloning interface for smart pointers.
Definition: CObject.h:133
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:3520
GLfloat GLfloat p
Definition: glext.h:5587
std::vector< const TRuntimeClassId * > BASE_IMPEXP getAllRegisteredClassesChildrenOf(const TRuntimeClassId *parent_id)
Like getAllRegisteredClasses(), but filters the list to only include children clases of a given base ...
std::vector< T1 > operator*(const std::vector< T1 > &a, const std::vector< T2 > &b)
a*b (element-wise multiplication)
Definition: ops_vectors.h:59
A wrapper class for pointers that can be safely copied with "=" operator without problems.
Definition: safe_pointers.h:64
CObjectPtr(CObject *data)
Definition: CObject.h:143



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019