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



Page generated by Doxygen 1.8.3 for MRPT 0.9.6 SVN: at Fri Feb 15 22:05:02 EST 2013