Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile

About CObect , CRuntimeClass and related macros.

2.72/5 (6 votes)
29 Mar 20072 min read 1  
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).

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here