CObect , CRuntimeClass and related macros





3.00/5 (5 votes)
Apr 2, 2007
2 min read

28912
A project that will dynamically create an object from a class
Introduction
When I was making a project that will dynamically create an object from a class,
I decided that the CObject
class should be the basis for all classes.
But why was it necessary to make a CObject
the base class? I went
searching on Code Project.
Unfortunately I didn't find an explanation.
Rather I created more questions, they are:
- Why should
CObject
be a base class and how we can be facilitate this? - What is
CRuntimeClass
? What is theRUNTIME_CLASS
macro? - What are all these macros:
DECLARE_DYNAMIC
IMPLEMENT_DYNAMIC
DECLARE_DYNCREATE
IMPLEMENT_DYNCREATE
I have tried to describe all of them with simple and easy examples. I have even explained the use of some important member functions of these classes and structures. Such as:
IsKindOf
GetRuntimeClass
CreateObject
FromName
IsDerivedFrom
Answers
- If you derive a class from
CObject
, then you will get this kind of support run-time class information, dynamic creation, and serialization. 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 structures from the name of a given class name.RUNTIME_CLASS
(class_name): the class name should not enclosed in quotation marks. Inside this class,DECLARE_DYNAMIC
macro must be used.- See the table. This is not same as MSDN's table:
Figure 1
Using the code with examples
If you follow all the examples, 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_DerivedpObj;
BOOL bCheck = RuntimeCkeck(&pObj);//check class name is correct or not
//BOOL bCheck =
RuntimeCkeck(RUNTIME_CLASS(CMyRuntime));
}
Up to here all discussion has been about:
CObject
DECLARE_DYNAMIC
IMPLEMENT_DYNAMIC
IsKindOf
GetRuntimeClass()
m_lpszClassName
In the above example you can use the CRuntimeClass::IsDerivedFrom((RUNTIME_CLASS(CMyRuntime))
function, but you can't use CRuntimeClass::CreateObject()
,
because you did not use the DECLARE_DYNCREATE
and the 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: An easy and simple way of learning this is to just copy the code and debug with break point.
Also, I didn't discuss Serialization here, though this is also part of this topic.
If there are any suggestions, requests or problems please inform me.