Main MRPT website > C++ reference
MRPT logo
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-2014, 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/utils/utils_defs.h>
14 
15 namespace mrpt
16 {
17  namespace utils
18  {
19  /** @name RTTI classes and functions
20  @{ */
21 
23 
24  /** A smart pointer to a CObject object
25  * \note Declared as a class instead of a typedef to avoid multiple defined symbols when linking dynamic libs.
26  * \ingroup mrpt_base_grp
27  */
29  {
31  public:
32  inline CObjectPtr() : BASE() {}
33  explicit inline CObjectPtr(const CObject& data) : BASE(data) {}
34  explicit inline CObjectPtr(CObject* data) : BASE(data) { }
35  inline CObjectPtr& operator=(const CObject& data) { BASE::operator=(data); return *this; }
36  inline CObjectPtr& operator=(const CObjectPtr& r) { BASE::operator=(r); return *this; }
37  };
38 
39  /** A structure that holds runtime class type information. Use CLASS_ID(<class_name>) to get a reference to the class_name's TRuntimeClassId descriptor.
40  * \ingroup mrpt_base_grp
41  */
43  {
44  const char* className;
45  /** Create an object of the related class, or NULL if it is virtual. */
46  mrpt::utils::CObject* (*ptrCreateObject)();
47  /** Gets the base class runtime id. */
48  const TRuntimeClassId* (*getBaseClass)();
49 
50  // Operations
51  mrpt::utils::CObject* createObject() const;
52  bool derivedFrom(const TRuntimeClassId* pBaseClass) const;
53  bool derivedFrom(const char* pBaseClass_name) const;
54 
55  };
56 
57  /** A wrapper class for a "TRuntimeClassId *", well-defined with respect to copy operators and constructors. \ingroup mrpt_base_grp
58  */
60 
61  /** Register a class into the MRPT internal list of "CSerializable" descendents.
62  * Used internally in the macros DEFINE_SERIALIZABLE, etc...
63  * \sa getAllRegisteredClasses, CStartUpClassesRegister
64  */
66 
67  /** Mostly for internal use within mrpt sources, to handle exceptional cases with multiple serialization names for backward compatibility (CMultiMetricMaps, CImage,...)
68  */
69  void BASE_IMPEXP registerClassCustomName(const char*customName, const TRuntimeClassId* pNewClass);
70 
71  /** Returns a list with all the classes registered in the system through mrpt::utils::registerClass.
72  * \sa registerClass, findRegisteredClass
73  */
74  std::vector<const mrpt::utils::TRuntimeClassId*> BASE_IMPEXP getAllRegisteredClasses();
75 
76  /** Return info about a given class by its name, or NULL if the class is not registered
77  * \sa registerClass, getAllRegisteredClasses
78  */
79  const TRuntimeClassId BASE_IMPEXP * findRegisteredClass(const std::string &className);
80 
81 
82  /** Access to runtime class ID for a defined class name.
83  */
84  #define CLASS_ID(class_name) static_cast<const mrpt::utils::TRuntimeClassId*>(&class_name::class##class_name)
85 
86  /** Access to runtime class ID for a defined class name.
87  */
88  #define CLASS_ID_NAMESPACE(class_name,namespaceName) static_cast<const mrpt::utils::TRuntimeClassId*>(&namespaceName::class_name::class##class_name)
89 
90  /** Access to runtime class ID for a defined template class name.
91  */
92  #define CLASS_ID_TEMPLATE(class_name,T) static_cast<const mrpt::utils::TRuntimeClassId*>(& template <class T> class_name<T>::class##class_name)
93 
94  /** Evaluates to true if the given pointer to an object (derived from mrpt::utils::CSerializable) is of the given class. */
95  #define IS_CLASS( ptrObj, class_name ) ((ptrObj)->GetRuntimeClass()==CLASS_ID(class_name))
96 
97  /** 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. */
98  #define IS_DERIVED( ptrObj, class_name ) ((ptrObj)->GetRuntimeClass()->derivedFrom(CLASS_ID(class_name)))
99 
100  /** Auxiliary structure used for CObject-based RTTI. \ingroup mrpt_base_grp */
102  {
104  {
105  registerClass(pNewClass);
106  }
107  };
108 
109 
110  /** The virtual base class of all MRPT classes with a unified RTTI system.
111  * For each class named <code>CMyClass</code>, a new type named <code>CMyClassPtr</code> will be created as a smart pointer suitable for
112  * keeping referencing count smart pointers to objects of that class. By default the base class of all these smart pointers is CObjectPtr.
113  * \sa mrpt::utils::CSerializable \ingroup mrpt_base_grp
114  */
116  {
117  protected:
118  static mrpt::utils::TRuntimeClassId* _GetBaseClass();
119  public:
121 
122  /** Returns information about the class of an object in runtime. */
124  {
125  return CLASS_ID(CObject);
126  }
127 
128  /** Returns a copy of the object, indepently of its class. */
129  virtual CObject *duplicate() const = 0;
130 
131  /** 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). */
132  inline mrpt::utils::CObjectPtr duplicateGetSmartPtr() const { return mrpt::utils::CObjectPtr( this->duplicate() ); }
133 
134  /** Cloning interface for smart pointers */
135  inline CObject *clone() const { return duplicate(); }
136 
137  virtual ~CObject() { }
138 
139  }; // End of class def.
140 
141 
142  /** 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 */
143  #define DEFINE_MRPT_OBJECT_CUSTOM_LINKAGE(class_name, _STATIC_LINKAGE_, _VIRTUAL_LINKAGE_) \
144  /*! @name RTTI stuff */ \
145  /*! @{ */ \
146  protected: \
147  _STATIC_LINKAGE_ const mrpt::utils::TRuntimeClassId* _GetBaseClass(); \
148  _STATIC_LINKAGE_ mrpt::utils::CLASSINIT _init_##class_name;\
149  public: \
150  /*! A typedef for the associated smart pointer */ \
151  typedef class_name##Ptr SmartPtr; \
152  _STATIC_LINKAGE_ mrpt::utils::TRuntimeClassId class##class_name; \
153  _STATIC_LINKAGE_ const mrpt::utils::TRuntimeClassId *classinfo; \
154  _VIRTUAL_LINKAGE_ const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const; \
155  _STATIC_LINKAGE_ mrpt::utils::CObject* CreateObject(); \
156  _STATIC_LINKAGE_ class_name##Ptr Create(); \
157  _VIRTUAL_LINKAGE_ mrpt::utils::CObject *duplicate() const; \
158  /*! @} */ \
159  public: \
160  EIGEN_MAKE_ALIGNED_OPERATOR_NEW \
161 
162  /** This declaration must be inserted in all CObject classes definition, within the class declaration. */
163  #define DEFINE_MRPT_OBJECT(class_name) \
164  DEFINE_MRPT_OBJECT_CUSTOM_LINKAGE(class_name, static /*none*/, virtual /*none*/)
165 
166  // This macro is a workaround to avoid possibly empty arguments to MACROS (when _LINKAGE_ evals to nothing...)
167  #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, _LINKAGE_ ) \
168  DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE2(class_name, base_name, _LINKAGE_ class_name)
169 
170  // Use this one when there is NO import/export macro:
171  #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_NO_LINKAGE(class_name, base_name) \
172  DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE2(class_name, base_name, class_name)
173 
174  /** This declaration must be inserted in all CObject classes definition, before the class declaration.
175  */
176  #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE2(class_name, base_name, class_name_LINKAGE_ ) \
177  class class_name_LINKAGE_; \
178  /*! The smart pointer type for the associated class */ \
179  struct class_name_LINKAGE_##Ptr : public base_name##Ptr \
180  { \
181  typedef class_name value_type; \
182  inline class_name##Ptr() : base_name##Ptr(static_cast<base_name*>(NULL)) { } \
183  inline explicit class_name##Ptr(class_name* p) : base_name##Ptr( reinterpret_cast<base_name*>(p) ) { } \
184  inline explicit class_name##Ptr(const base_name##Ptr & p) : base_name##Ptr(p) { ASSERTMSG_( p->GetRuntimeClass()->derivedFrom(#class_name),::mrpt::format("Wrong typecasting of smart pointers: %s -> %s",p->GetRuntimeClass()->className, #class_name) ) } \
185  inline explicit class_name##Ptr(const mrpt::utils::CObjectPtr & p) : base_name##Ptr(p) { ASSERTMSG_( p->GetRuntimeClass()->derivedFrom(#class_name),::mrpt::format("Wrong typecasting of smart pointers: %s -> %s",p->GetRuntimeClass()->className, #class_name) ) } \
186  inline void setFromPointerDoNotFreeAtDtor(const class_name* p) { this->set(const_cast<mrpt::utils::CObject*>(reinterpret_cast<const mrpt::utils::CObject*>(p))); m_holder->increment(); } \
187  /*! Return the internal plain C++ pointer */ \
188  inline class_name * pointer() { return reinterpret_cast<class_name*>(base_name##Ptr::pointer()); } \
189  /*! Return the internal plain C++ pointer (const) */ \
190  inline const class_name * pointer() const { return reinterpret_cast<const class_name*>(base_name##Ptr::pointer()); } \
191  inline class_name* operator ->(void) { return reinterpret_cast<class_name*>( base_name##Ptr::operator ->() ); } \
192  inline const class_name* operator ->(void) const { return reinterpret_cast<const class_name*>( base_name##Ptr::operator ->() ); } \
193  inline class_name& operator *(void) { return *reinterpret_cast<class_name*>( base_name##Ptr::operator ->() ); } \
194  inline const class_name& operator *(void) const { return *reinterpret_cast<const class_name*>( base_name##Ptr::operator ->() ); } \
195  };
196 
197 
198  // This macro is a workaround to avoid possibly empty arguments to MACROS (when _LINKAGE_ evals to nothing...)
199  #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_LINKAGE(class_name,_LINKAGE_) \
200  DEFINE_MRPT_OBJECT_PRE_CUSTOM_LINKAGE2(class_name, _LINKAGE_ class_name)
201 
202  // Use this macro when there is NO export/import macro:
203  #define DEFINE_MRPT_OBJECT_PRE_NO_LINKAGE(class_name) \
204  DEFINE_MRPT_OBJECT_PRE_CUSTOM_LINKAGE2(class_name, class_name)
205 
206  // This one is almost identical to the one above, but without a member:
207  /** This declaration must be inserted in all CObject classes definition, before the class declaration. */
208  #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_LINKAGE2(class_name,class_name_LINKAGE_) \
209  class class_name_LINKAGE_; \
210  /*! The smart pointer type for the associated class */ \
211  struct class_name_LINKAGE_##Ptr : public mrpt::utils::CObjectPtr \
212  { \
213  inline class_name##Ptr() : mrpt::utils::CObjectPtr(static_cast<mrpt::utils::CObject*>(NULL)) { } \
214  inline explicit class_name##Ptr(class_name* p) : mrpt::utils::CObjectPtr( reinterpret_cast<mrpt::utils::CObject*>(p) ) { } \
215  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) ) } \
216  inline void setFromPointerDoNotFreeAtDtor(const class_name* p) { this->set(const_cast<mrpt::utils::CObject*>(reinterpret_cast<const mrpt::utils::CObject*>(p))); m_holder->increment(); } \
217  /*! Return the internal plain C++ pointer */ \
218  inline class_name * pointer() { return reinterpret_cast<class_name*>(mrpt::utils::CObjectPtr::pointer()); } \
219  /*! Return the internal plain C++ pointer (const) */ \
220  inline const class_name * pointer() const { return reinterpret_cast<const class_name*>(mrpt::utils::CObjectPtr::pointer()); } \
221  inline class_name* operator ->(void) { return reinterpret_cast<class_name*>( mrpt::utils::CObjectPtr::operator ->() ); } \
222  inline const class_name* operator ->(void) const { return reinterpret_cast<const class_name*>( mrpt::utils::CObjectPtr::operator ->() ); } \
223  inline class_name& operator *(void) { return *reinterpret_cast<class_name*>( mrpt::utils::CObjectPtr::operator ->() ); } \
224  inline const class_name& operator *(void) const { return *reinterpret_cast<const class_name*>( mrpt::utils::CObjectPtr::operator ->() ); } \
225  };
226 
227  /** This declaration must be inserted in all CObject classes definition, before the class declaration.
228  */
229  #define DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE(class_name, base_name) \
230  DEFINE_MRPT_OBJECT_PRE_CUSTOM_BASE_LINKAGE(class_name, base_name, BASE_IMPEXP )
231 
232  /** This declaration must be inserted in all CObject classes definition, before the class declaration.
233  */
234  #define DEFINE_MRPT_OBJECT_PRE(class_name) \
235  DEFINE_MRPT_OBJECT_PRE_CUSTOM_LINKAGE(class_name, BASE_IMPEXP ) // This macro is valid for classes within mrpt-base only.
236 
237  /** This must be inserted in all CObject classes implementation files
238  */
239  #define IMPLEMENTS_MRPT_OBJECT(class_name, base,NameSpace) \
240  mrpt::utils::CObject* NameSpace::class_name::CreateObject() \
241  { return static_cast<mrpt::utils::CObject*>( new NameSpace::class_name ); } \
242  NameSpace::class_name##Ptr NameSpace::class_name::Create() \
243  { return NameSpace::class_name##Ptr( new NameSpace::class_name ); } \
244  const mrpt::utils::TRuntimeClassId* NameSpace::class_name::_GetBaseClass() \
245  { return CLASS_ID(base); } \
246  mrpt::utils::TRuntimeClassId NameSpace::class_name::class##class_name = { \
247  #class_name, NameSpace::class_name::CreateObject, &class_name::_GetBaseClass }; \
248  const mrpt::utils::TRuntimeClassId *NameSpace::class_name::classinfo = & NameSpace::class_name::class##class_name; \
249  const mrpt::utils::TRuntimeClassId* NameSpace::class_name::GetRuntimeClass() const \
250  { return CLASS_ID_NAMESPACE(class_name,NameSpace); } \
251  mrpt::utils::CLASSINIT NameSpace::class_name::_init_##class_name(CLASS_ID(base)); \
252  mrpt::utils::CObject * NameSpace::class_name::duplicate() const \
253  { return static_cast<mrpt::utils::CObject*>( new NameSpace::class_name(*this) ); }
254 
255 
256  /** This declaration must be inserted in virtual CSerializable classes definition:
257  */
258  #define DEFINE_VIRTUAL_MRPT_OBJECT(class_name) \
259  /*! @name RTTI stuff */ \
260  /*! @{ */ \
261  protected: \
262  static const mrpt::utils::TRuntimeClassId* _GetBaseClass(); \
263  public: \
264  static const mrpt::utils::TRuntimeClassId class##class_name; \
265  virtual const mrpt::utils::TRuntimeClassId* GetRuntimeClass() const; \
266  friend class mrpt::utils::CStream; \
267  /*! @} */ \
268 
269  /** This must be inserted as implementation of some required members for
270  * virtual CSerializable classes:
271  */
272  #define IMPLEMENTS_VIRTUAL_MRPT_OBJECT(class_name, base_class_name,NameSpace) \
273  const mrpt::utils::TRuntimeClassId* class_name::_GetBaseClass() \
274  { return CLASS_ID(base_class_name); } \
275  const mrpt::utils::TRuntimeClassId class_name::class##class_name = { \
276  #class_name, NULL, &class_name::_GetBaseClass }; \
277  const mrpt::utils::TRuntimeClassId* class_name::GetRuntimeClass() const \
278  { return CLASS_ID(class_name); }
279 
280  /** @} */ // end of RTTI
281 
282  } // End of namespace
283 } // End of namespace
284 
285 // JL: I want these operators to reside in std so STL algorithms can always find them.
286 namespace std
287 {
288  /** This operator enables comparing two smart pointers with "==" to test whether they point to the same object.
289  */
290  template <typename T,typename C, typename COUNTER>
292  return a.aliases(b);
293  }
294  /** This operator enables comparing two smart pointers with "!=" to test whether they don't point to the same object.
295  */
296  template <typename T,typename C, typename COUNTER>
298  return !a.aliases(b);
299  }
300 }
301 
302 #endif
Auxiliary structure used for CObject-based RTTI.
Definition: CObject.h:101
std::vector< const mrpt::utils::TRuntimeClassId * > BASE_IMPEXP getAllRegisteredClasses()
Returns a list with all the classes registered in the system through mrpt::utils::registerClass.
void BASE_IMPEXP registerClass(const mrpt::utils::TRuntimeClassId *pNewClass)
Register a class into the MRPT internal list of "CSerializable" descendents.
safe_ptr< TRuntimeClassId > TRuntimeClassIdPtr
A wrapper class for a "TRuntimeClassId *", well-defined with respect to copy operators and constructo...
Definition: CObject.h:59
virtual const mrpt::utils::TRuntimeClassId * GetRuntimeClass() const
Returns information about the class of an object in runtime.
Definition: CObject.h:123
STL namespace.
A smart pointer to a CObject object.
Definition: CObject.h:28
CObjectPtr(const CObject &data)
Definition: CObject.h:33
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:132
virtual ~CObject()
Definition: CObject.h:137
static const mrpt::utils::TRuntimeClassId classCObject
Definition: CObject.h:120
#define CLASS_ID(class_name)
Access to runtime class ID for a defined class name.
Definition: CObject.h:84
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void BASE_IMPEXP registerClassCustomName(const char *customName, const TRuntimeClassId *pNewClass)
Mostly for internal use within mrpt sources, to handle exceptional cases with multiple serialization ...
bool aliases(const smart_ptr_base< T, C, COUNTER > &) const
CLASSINIT(const mrpt::utils::TRuntimeClassId *pNewClass)
Definition: CObject.h:103
A structure that holds runtime class type information.
Definition: CObject.h:42
The virtual base class of all MRPT classes with a unified RTTI system.
Definition: CObject.h:115
CObjectPtr(CObject *data)
Definition: CObject.h:34
CObjectPtr & operator=(const CObjectPtr &r)
Definition: CObject.h:36
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.
const char * className
Definition: CObject.h:44
CObject * clone() const
Cloning interface for smart pointers.
Definition: CObject.h:135
stlplus::smart_ptr_clone< CObject > BASE
Definition: CObject.h:30
CObjectPtr & operator=(const CObject &data)
Definition: CObject.h:35



Page generated by Doxygen 1.8.14 for MRPT 1.1.0 SVN: at lun oct 28 00:54:49 CET 2019 Hosted on:
SourceForge.net Logo