65.9K
CodeProject is changing. Read more.
Home

About CObect , CRuntimeClass and related macros.

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.72/5 (6 votes)

Mar 29, 2007

2 min read

viewsIcon

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 -

Screenshot - RuntimeTable.jpg

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).