MFC: CObject class (Part – 4)

In our previous articles we have discussed about CObject‘s “run-time class information”, “serialization support” and “dynamic object creation” features. In this articles I am going to discuss about CObject‘s “object diagnostic support” feature.

Object diagnostic feature is useful to provide additional information about the objects; usually this information will be displayed in the output window in the integrated development environment (IDE).

CObject class provides a member function Dump to support this feature. As object dumping is makes sense only when debugging the program; Dump method is only available in DEBUG mode. This method not available in RELEASE mode of the application.

The class which is derived from CObject class must override Dump method in order to avail “object diagnostic support” feature. The declaration of Dump method is looks like below:

#ifdef _DEBUG
    virtual void Dump(CDumpContext& dc) const;
#endif

Observe that the declaration is enclosed within #ifdef _DEBUG and #endif directives. That means Dump method is available in DEBUG mode only. Obviously the overridden Dump method also must be enclosed within #ifdef _DEBUG and #endif directives.

Dump method writes the object’s information into a dump context; which is similar to an I/O stream. We need to pass dump context information through Dump method; hence CDumpContext type as an argument to Dump method. CDumpContext supports to display object’s diagnostic output in the form of readable text. Unlike Dump method which is only available in DEBUG mode; CDumpContext class is available in both DEBUG and RELEASE modes.

The Dump method implementation will looks like below:

#ifdef _DEBUG
void SampleClass::Dump(CDumpContext& dc) const
{
    // Call the base class's version first.
    CObject::Dump(dc);

    // Add your specialized code here.
    dc << "You can provide class members here.";
}
#endif

Usually we will print the values of the class members through Dump method using CDumpContext object. Before calling current class’s Dump; we should class its base class’s version. So, this way we can have all the values in the class hierarchy. This will helpful to analyze any errors in the program.

Now we need to call this function. We can call this function from anywhere. Remember that as Dump method is available only in DEBUG mode; we should include Dump method calls within #ifdef _DEBUG and #endif directives. The function call looks like below:

#ifdef _DEBUG
	Dump(afxDump);
#endif

Where afxDump is the dump context automatically created by MFC framework. If we want to create our own dump context, we can create and pass the object when calling Dump method.

To create our own CDumpContext object we need to first create a CFile object to route the dump output. Below is the code:

#ifdef _DEBUG
	CFile file(L"c:\\temp.dump", CFile::modeCreate | CFile::typeBinary | CFile::modeWrite);
	CDumpContext dc(&file);
	Dump(dc);
#endif

Above code will print the dump output into the file “C:\\temp.dump”.

We can control the depth of dump information using CDumpContext‘s GetDepth and SetDepth member functions. By default CDumpContext will do the shallow dump; but we can enable to do the deep dump by setting depth value through its SetDepth member function. Remember that in our class’s Dump method, we need to add conditional statements to instruct what to print for shallow dump and what to print for deep dump.

Another diagnostic support method CObject provides is, AssertValid method. Like Dump method, AssertValid method is also available only in DEBUG modes. AssertValid method validates the internal state of the object. The function declaration looks like below:

#ifdef _DEBUG
	virtual void AssertValid() const;
#endif

The derived class should override AssertValid function to provide diagnostic support; it should be internally called its base class’s AssertValid method. When we call this function, it may assert and display a message with line number and filename where the assertion failed; after that the program will be terminated. The implementation function looks like below:

#ifdef _DEBUG
	void SampleClass::AssertValid() const
	{
   		CObject::AssertValid();

   		/* Add some ASSERT macros here */ 
   		// ASSERT(<validate member data here.>);
   		// For example: ASSERT(m_member_variable > 0);
	}
#endif

Another important diagnostic support CObject provides is through its memory management operators new and delete. Unlike “C++” new and delete operators; CObject‘s new and delete operators provide more details about memory allocation to track memory leaks. In DEBUG mode these operators will also records line number and file name information for each allocation.

These are the overall benefits the derived class will get when it is derived from CObject class.

**

Leave a Reply