About CObect , CRuntimeClass and related macros.






2.72/5 (6 votes)
Mar 29, 2007
2 min read

27942
What is the useful of CObject , CRuntimeClass and related macros.
Introduction
When I was making a project that will dynamically create object of a class,
I was suggested that to make all the class's base should be CObject class.
But to know why it is necessary to make CObject as base class. I was searching in code project.
Unfortunately I didn't get any better explanation.
Rather I created some more question , they are –
1. Why CObject should be base class and how we can be facilitate by this ?
2. What is CRuntimeClass ? What is RUNTIME_CLASS macro?
3. What are all this macro –
DECLARE_DYNAMIC and IMPLEMENT_DYNAMIC, the DECLARE_DYNCREATE and IMPLEMENT_DYNCREATE.
I have tried to describe all of them with simple and easy example.
Even I have explained the use of some important member function of these class and structure.
Like –
IsKindOf , GetRuntimeClass, CreateObject, FromName, IsDerivedFrom.
Answer of previous question that I created :
Ans.1 :
if you derive a class from CObject then, you will get this kind of support
run-time class information, dynamic creation, and serialization.
Ans.2 :
CRunitmeClass is a structure and does not have a base class.
RUNTIME_CLASS this macro is used to Get the object of run-time class structure
from the name of a given class name.
RUNTIME_CLASS(class_name)
//class name should not enclosed in quotation marks and inside this class DECLARE_DYNAMIC macro must be used.
Ans.3 : See the table . This is not same as MSDN's table -
Using the code with example :
If you follow all the example , it will be easy to grab the total concept
//In interface file
//CMyRuntime should be derived from CObject for run time support
class CMyRuntime : public CObject { DECLARE_DYNAMIC(CMyRuntime) // for run time support public: BOOL ShowName(CString strName); }; class CMyRuntime_Derived : public CMyRuntime { DECLARE_DYNAMIC(CMyRuntime_Derived) // for run time support public: BOOL ShowNameDrvd(CString strName); };
//In implementation file
IMPLEMENT_DYNAMIC(CMyRuntime, CObject) BOOL CMyRuntime::ShowName(CString strName) { AfxMessageBox(strName); return TRUE; } IMPLEMENT_DYNAMIC(CMyRuntime_Derived, CMyRuntime) BOOL CMyRuntime_Derived::ShowNameDrvd(CString strName) { AfxMessageBox(strName); return TRUE; } //BOOL RuntimeCkeck(CRuntimeClass *pRTClass) BOOL RuntimeCkeck(CObject* pObj) { //first use // To get class name CRuntimeClass *pClass = pObj.GetRuntimeClass(); LPCSTR className = pClass->m_lpszClassName; //or you can use this /*if(strcmp(pRTClass->m_lpszClassName, "CMyRuntime" ) == 0) { //do whatever }*/ //second use //To be sure that, is there any relation between this two class //e.g. "CMyRuntime_Derived" is base or child of "CMyRuntime" CMyRuntime_Derived pMyruntime; BOOL bRTCheck = pMyruntime.IsKindOf(RUNTIME_CLASS(CMyRuntime)); return bRTCheck; } //In any other file void AnyFunction() { CMyRuntime_Derived pObj; BOOL bCheck = RuntimeCkeck(&pObj); //check class name is correct or not //BOOL bCheck = RuntimeCkeck(RUNTIME_CLASS(CMyRuntime)); }
Upto here all discussion was about -
CObject, DECLARE_DYNAMIC, IMPLEMENT_DYNAMIC, IsKindOf, GetRuntimeClass(). (and m_lpszClassName).
In the above example you can use CRuntimeClass::IsDerivedFrom((RUNTIME_CLASS(CMyRuntime)) function
But
you cann't use CRuntimeClass::CreateObject() ,
because you did not use DECLARE_DYNCREATE and IMPLEMENT_DYNCREATE macro.
Now see the use of CRuntimeClass::CreateObject() function -
//In interface file
class CMyRuntime : public CObject { DECLARE_DYNCREATE(CMyRuntime) // for run time support public: BOOL ShowName(CString strName); }; class CMyRuntime_Derived : public CMyRuntime { DECLARE_DYNCREATE(CMyRuntime_Derived) // for run time support public: BOOL ShowNameDrvd(CString strName); };
//In implementation file
CObject* GlobalObjectCreator(CRuntimeClass *pClass) { CObject *pObject = NULL; if(pClass == NULL) { return pObject; } //if CMyRuntime_Derived is not derived from CMyRuntime, it will return 0 BOOL bRelation = pClass->IsDerivedFrom(RUNTIME_CLASS(CMyRuntime)); pObject = pClass->CreateObject(); if(pObject == NULL) { AfxMessageBox(_T("Out of memory creating an object ")); } //if you use any other class name instead of CMyRuntime, it will return 0. bRelation = pObject->IsKindOf(RUNTIME_CLASS(CMyRuntime)); return pObject; } //----- IMPLEMENT_DYNCREATE(CMyRuntime, CObject) BOOL CMyRuntime::ShowName(CString strName) { AfxMessageBox(strName); return 1; } IMPLEMENT_DYNCREATE(CMyRuntime_Derived, CMyRuntime) BOOL CMyRuntime_Derived::ShowNameDrvd(CString strName) { AfxMessageBox(strName); return TRUE; } //In any other file void AnyFunction() { CMyRuntime_Derived* pMyRuntime = NULL; pMyRuntime = (CMyRuntime_Derived*)GlobalObjectCreator(RUNTIME_CLASS(CMyRuntime_Derived)); pMyRuntime->ShowName(_T("Hi")); }
Note :
Easy and simple way of learing of this is , just copy the code and debug with break point.
Important:
Here I didn't discus about Serialization, that is also part of this topic.
If there is any suggestion , request or any problem please inform me.
About me :
I am Mahfuzur Rahman (Software Engineer).