123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- #pragma once
- #include <assert.h>
- #ifndef _XDWRTTI_DLL
- #define XDWRTTI_API _declspec(dllimport)
- #else
- #define XDWRTTI_API _declspec(dllexport)
- #endif
- //-----------------------------------------------------------------------------
- //
- // 实现自己的 RTTI (Run Time Type Idendify)
- //
- // 代码改造自 MFC, 但是做了简化
- //
- //-----------------------------------------------------------------------------
- class XDWObject;
- struct RTTIClass
- {
- // Attributes
- LPCSTR m_lpszClassName;
- int m_nObjectSize;
- RTTIClass * m_pBaseClass;
- XDWObject * (PASCAL * m_pfnCreateObject) (); // NULL => abstract class
- bool IsDerivedFrom (const RTTIClass * pBaseClass) const;
- XDWObject * CreateObject ();
- };
- inline bool RTTIClass::IsDerivedFrom (const RTTIClass * pBaseClass) const
- {
- assert (this != NULL);
- assert (pBaseClass != NULL);
- // simple SI case
- const RTTIClass * pClassThis = this;
- while (pClassThis != NULL)
- {
- if (pClassThis == pBaseClass)
- return true;
- pClassThis = pClassThis->m_pBaseClass;
- }
- return false; // walked to the top, no match
- }
- #define DECLARE_RTTI(class_name) \
- protected: \
- static RTTIClass * PASCAL _GetBaseClass (); \
- public: \
- static const RTTIClass class##class_name; \
- static RTTIClass * PASCAL GetThisClass (); \
- virtual RTTIClass * GetRTTIClass () const;
- // dynamically constructable
- #define DECLARE_RTTI_DYNCREATE(class_name) \
- DECLARE_RTTI(class_name) \
- static XDWObject * PASCAL CreateObject();
- #define __IMPLEMENT_RTTI(class_name, base_class_name, func) \
- __declspec(selectany) const RTTIClass class_name::class##class_name = { \
- #class_name, sizeof(class class_name), RTTI_CLASS (base_class_name), func}; \
- RTTIClass * PASCAL class_name::_GetBaseClass() \
- { return RTTI_CLASS(base_class_name); } \
- RTTIClass * PASCAL class_name::GetThisClass() \
- { return _RTTI_CLASS(class_name); } \
- RTTIClass * class_name::GetRTTIClass() const \
- { return _RTTI_CLASS(class_name); }
- #define IMPLEMENT_RTTI(class_name, base_class_name) __IMPLEMENT_RTTI(class_name, base_class_name, NULL)
- #define IMPLEMENT_RTTI_DYNCREATE(class_name, base_class_name) \
- XDWObject * PASCAL class_name::CreateObject() \
- { return new class_name; } \
- __IMPLEMENT_RTTI(class_name, base_class_name, class_name::CreateObject)
- #define _RTTI_CLASS(class_name) ((RTTIClass *)(&class_name::class##class_name))
- #define RTTI_CLASS(class_name) (class_name::GetThisClass())
- #define ASSERT_RTTI(class_name, object) ASSERT((object)->IsKindOf(RTTI_CLASS(class_name)))
- class XDWRTTI_API XDWObject
- {
- public:
- virtual RTTIClass * GetRTTIClass () const;
- virtual ~XDWObject() = 0; // virtual destructors are necessary
- protected:
- XDWObject ();
- private:
- XDWObject (const XDWObject & objectSrc); // no implementation
- void operator = (const XDWObject & objectSrc); // no implementation
- public:
- bool IsKindOf (const RTTIClass * pClass) const;
- template <typename T> T * As ()
- {
- if (this != NULL && this->IsKindOf (RTTI_CLASS (T)))
- return (T *) this;
- else
- return NULL;
- }
- template <typename T> const T * As () const
- {
- if (this != NULL && this->IsKindOf (RTTI_CLASS (T)))
- return (const T *) this;
- else
- return NULL;
- }
- template <typename T> bool Is () const
- {
- return (IsKindOf (RTTI_CLASS (T)));
- }
- public:
- static const RTTIClass classXDWObject;
- static RTTIClass * PASCAL _GetBaseClass();
- static RTTIClass * PASCAL GetThisClass();
- };
- inline XDWObject::XDWObject ()
- { }
- inline XDWObject::~XDWObject ()
- { }
- inline RTTIClass * XDWObject::GetRTTIClass () const
- {
- return _RTTI_CLASS (XDWObject);
- }
- inline RTTIClass * PASCAL XDWObject::_GetBaseClass()
- {
- return NULL;
- }
- inline RTTIClass * PASCAL XDWObject::GetThisClass()
- {
- return _RTTI_CLASS (XDWObject);
- }
- inline bool XDWObject::IsKindOf (const RTTIClass * pClass) const
- {
- assert (this != NULL);
- // simple SI case
- RTTIClass * pClassThis = GetRTTIClass ();
- assert (pClassThis);
- return pClassThis->IsDerivedFrom (pClass);
- }
- inline XDWObject * RTTIClass::CreateObject ()
- {
- assert (this != NULL);
- if (m_pfnCreateObject == NULL)
- {
- assert (false);
- return NULL;
- }
- XDWObject * pObject = NULL;
- try
- {
- pObject = (*m_pfnCreateObject) ();
- }
- catch (...)
- {
- }
- return pObject;
- }
|