MFC: CObject class (Part – 3)

As of now we have discussed about CObject class features “run-time class information” and “serialization support” in our previous articles MFC: CObject class (Part – 1) and MFC: CObject class (Part – 2) respectively. In this article I am going to discuss about CObject‘s other feature “dynamic object creation”.

To enable “dynamic object creation” feature for the class which is derived from CObject class; we need to add DECLARE_DYNCREATE macro in the class’ header file and we must also need to add IMPLEMENT_DYNCREATE macro in class’ implementation file. After adding these macros; MFC enables to use CRuntimeClass‘s CreateObject method.

CreateObject method is useful to create dynamic objects for the given classes. This is very helpful function; MFC internally use this function to create class’ objects dynamically. CRuntimeClass provides multiple versions of CreateObject function. One is its class member and another one is a static function. The syntaxes of these are:

CObject* CreateObject( );

This method should be called using instance(s) of CRuntimeClass. To create a class from the string, we can use the below method. This is the static method of CRuntimeClass, so we can call this method directly; without using CRuntimeClass instance.

static CObject* PASCAL CreateObject(LPCSTR lpszClassName);

Both these methods return NULL value when failed to create an instance of a class.

Lets put these macros into our class “Shape” and create an instance of this class dynamically.

Step 1. Add DECLARE_DYNCREATE macro into “Shape” class header file. The syntax for this macro is:

DECLARE_DYNCREATE(<class name>)

Where <class name> is the name of the class.

After we added DECLARE_DYNCREATE macro to our class “Shape”; the class code looks like below:

// Shape.h
//
#include <afx.h>
#include <iostream>

class Shape : public CObject
{
public:
	Shape();

	DECLARE_DYNCREATE(Shape);
};

Step 2. Now important thing is we need to add IMPLEMENT_DYNCREATE macro into “Shape” class’s implementation file. The syntax of IMPLEMENT_DYNCREATE macro is like below:

IMPLEMENT_DYNCREATE(<class_name>, <base class name>)

Where <class name> is the name of the class and <base class name> is its base class name. Our class name is “Shape”, so we need to pass Shape as <class name> and our “Shape” class’s base class is CObject; hence we need to pass CObject as <base class name>.

After adding this macro, Shape class implementation file looks like below:

// Shape.cpp
//
#include "Shape.h"

using namespace std;

IMPLEMENT_DYNCREATE(Shape, CObject);

Shape::Shape()
{
	cout << "This is a Shape class." << endl;
}

Step 3. Our class Shape is enabled for dynamic object creation. That means we can create an instance of Shape class dynamically. As discussed above, CRuntimeClass‘s CreateObject method(s) are useful to create a class’s instance dynamically. Here we will use both these methods to create instances of Shape class. Usually we use below code to create an instance of Shape class.

Shape obj;

This is static creation of a class instance. To create an object dynamically:

Step 3.1. Create an instance of CRuntimeClass for Shape class.

CRuntimeClass *pRuntimeClass = RUNTIME_CLASS(Shape);

Step 3.2. Once we have CRuntimeClass‘s instance; call its CreateObject method to create an instance of Shape class.

pRuntimeClass->CreateObject();

OR

Step 3.1. Call CRuntimeClass‘s static version of CreateObject method to create an instance of Shape class dynamically.

CRuntimeClass::CreateObject("Shape");

Observe that here we are passing name of the class as a string.

Up on success; both above methods will return an instance pointer to CObject class.

Putting together the dynamic object creation code looks like below:

void main()
{
	// Method 1 - Object creation
	CObject *pobj1 = NULL;

	CRuntimeClass *pRuntimeClass = RUNTIME_CLASS(Shape);
	if ( pRuntimeClass != NULL )
		pobj1 = pRuntimeClass->CreateObject();

	if ( pobj1 != NULL )
	{
		if ( pobj1->IsKindOf(RUNTIME_CLASS(Shape)) )
			printf("This is an instance of Shape class.");

		delete pobj1;
	}

	// Method 2 - Object creation using static method
	CObject *pobj2 = CRuntimeClass::CreateObject("Shape");

	if ( pobj2 != NULL )
	{
		if ( pobj2->IsKindOf(RUNTIME_CLASS(Shape)) )
			printf("This is an instance of Shape class.");

		delete pobj2;
	}
}

From above code we have created Shape class object dynamically created using CRuntimeClass‘s CreateObject method(s). Method 2 may not create an instance for Shape class; by enable serialization support to Shape class to make it work.

Lets discuss about CObject‘s another feature “object diagnostic support” in our next article.

**

Leave a Reply