Click here to Skip to main content
15,868,164 members
Articles / Programming Languages / C++
Article

CObect , CRuntimeClass and related macros

Rate me:
Please Sign up or sign in to vote.
3.00/5 (5 votes)
2 Apr 20072 min read 28.1K   11   6
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:

  1. Why should CObject be a base class and how we can be facilitate this?
  2. What is CRuntimeClass? What is the RUNTIME_CLASS macro?
  3. 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

  1. If you derive a class from CObject, then you will get this kind of support run-time class information, dynamic creation, and serialization.
  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 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.
  3. See the table. This is not same as MSDN's table:

Screenshot - CObject___CRuntimeClass.jpg
Figure 1

Using the code with examples

If you follow all the examples, it will be easy to grab the total concept.

C++
//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:

C++
//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.

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


Written By
Enosis Solution, Dhaka
Bangladesh Bangladesh
Liveing in Dhaka.
Working at Enosis Solution.
Studied B.Sc. in Computer Science from Bangalore University.

Comments and Discussions

 
QuestionI need your help Pin
Member 1006688310-Sep-13 22:22
Member 1006688310-Sep-13 22:22 
AnswerRe: I need your help Pin
Mahfuzur Rahman.22-Oct-13 7:15
Mahfuzur Rahman.22-Oct-13 7:15 
Generaltypo... Pin
toxcct2-Apr-07 22:04
toxcct2-Apr-07 22:04 
GeneralRe: typo... Pin
Mahfuzur Rahman.2-Apr-07 23:40
Mahfuzur Rahman.2-Apr-07 23:40 
Generalgood article Pin
ThatsAlok2-Apr-07 19:24
ThatsAlok2-Apr-07 19:24 
Good article dude!


"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow


cheers,
Alok Gupta
Global Interface Table: An Easy Way to Marshal an Interface Pointer[new]
VC Forum Q&A :- I/ IV
Support CRY- Child Relief and You

GeneralRe: good article Pin
Mahfuzur Rahman.2-Apr-07 19:32
Mahfuzur Rahman.2-Apr-07 19:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.