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



Page generated by Doxygen 1.9.7 for MRPT 1.4.0 SVN: at Tue Jun 27 15:23:24 UTC 2023