dynamic_cast RTTI
: Pushkoff
dynamic_cast RTTI , , - , ...
: Pushkoff
dynamic_cast RTTI , , - , ...
class CType { const CType* mSuper; const char* mName; public: CType(const CType* parent, const char* name ): mSuper( parent), mName( name) {} inline bool Is( const CType* objtype ) const { while( objtype && objtype != this ) { objtype = objtype->mSuper; } return objtype == this; } inline const char* GetName( ) const { return mName; } }; #define DECLARE_GET_TYPE( cls) \ typedef cls Self; \ virtual const CType* GetType( ) const { return &Type( ); } #define DECLARE_OBJECT( cls,super) \ typedef super Super; \ static inline const CType& Type( ) { static const CType my_type( &cls::Super::Type( ), #cls ); return my_type; } \ DECLARE_GET_TYPE( cls) #define DECLARE_ROOT_OBJECT( cls) \ static inline const CType& Type( ) { static const CType my_type( 0, #cls ); return my_type; } \ DECLARE_GET_TYPE( cls) \ template <class T> static inline T* Cast( cls * obj ) \ { \ return GET_CLASS_TYPE( T)->Is( GET_OBJECT_TYPE( obj) ) ? ( T*)obj : NULL; \ } \ \ template <class T> static inline const T* Cast( const cls * obj ) \ { \ return GET_CLASS_TYPE( T)->Is( GET_OBJECT_TYPE( obj) ) ? ( T*)obj : NULL; \ } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #define GET_CLASS_TYPE( cls) ( &cls::Type( )) #define GET_CLASS_TYPE_NAME( cls) ( GET_CLASS_TYPE( cls)->GetName( )) #define GET_OBJECT_TYPE( obj) ( obj->GetType( )) #define GET_OBJECT_TYPE_NAME( obj) ( GET_OBJECT_TYPE( obj)->GetName( )) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <iostream> class Object { public: DECLARE_ROOT_OBJECT(Object) }; class ChildObject : public Object { public: DECLARE_OBJECT( ChildObject, Object) }; class SecondChildObject : public ChildObject { public: DECLARE_OBJECT( SecondChildObject, ChildObject) }; int main( ) { const Object *o1 = new Object( ), *o2 = new ChildObject( ), *o3 = new SecondChildObject( ); const ChildObject* derived = 0; const SecondChildObject* secondderived = 0; std::cout<< "o1 is " << GET_OBJECT_TYPE_NAME( o1 ) << std::endl; std::cout<< "o2 is " << GET_OBJECT_TYPE_NAME( o2 ) << std::endl; std::cout<< "o3 is " << GET_OBJECT_TYPE_NAME( o3 ) << std::endl << std::endl; derived = Object::Cast<ChildObject>( o1); std::cout<< "o1 is " << ( derived == 0 ? "not ": "") << GET_CLASS_TYPE_NAME( ChildObject) << std::endl; derived = Object::Cast<ChildObject>( o2); std::cout<< "o2 is " << ( derived == 0 ? "not ": "") << GET_CLASS_TYPE_NAME( ChildObject) << std::endl; derived = Object::Cast<ChildObject>( o3); std::cout<< "o3 is " << ( derived == 0 ? "not ": "") << GET_CLASS_TYPE_NAME( ChildObject) << std::endl << std::endl; secondderived = Object::Cast<SecondChildObject>( o1); std::cout<< "o1 is " << ( secondderived == 0 ? "not ": "") << GET_CLASS_TYPE_NAME( SecondChildObject) << std::endl; secondderived = Object::Cast<SecondChildObject>( o2); std::cout<< "o2 is " << ( secondderived == 0 ? "not ": "") << GET_CLASS_TYPE_NAME( SecondChildObject) << std::endl; secondderived = Object::Cast<SecondChildObject>( o3); std::cout<< "o3 is " << ( secondderived == 0 ? "not ": "") << GET_CLASS_TYPE_NAME( SecondChildObject) << std::endl << std::endl; return 0; } output: o1 is Object o2 is ChildObject o3 is SecondChildObject o1 is not ChildObject o2 is ChildObject o3 is ChildObject o1 is not SecondChildObject o2 is not SecondChildObject o3 is SecondChildObject