CObject Class

The principal base class for the Microsoft Foundation Class Library.

Syntax

class AFX_NOVTABLE CObject

Members

Protected Constructors

Name Description
CObject::CObject Default constructor.

Public Methods

Name Description
CObject::AssertValid Validates this object's integrity.
CObject::Dump Produces a diagnostic dump of this object.
CObject::GetRuntimeClass Returns the CRuntimeClass structure corresponding to this object's class.
CObject::IsKindOf Tests this object's relationship to a given class.
CObject::IsSerializable Tests to see whether this object can be serialized.
CObject::Serialize Loads or stores an object from/to an archive.

Public Operators

Name Description
CObject::operator delete Special delete operator.
CObject::operator new Special new operator.

Remarks

It serves as the root not only for library classes such as CFile and CObList, but also for the classes that you write. CObject provides basic services, including

  • Serialization support
  • Run-time class information
  • Object diagnostic output
  • Compatibility with collection classes

CObject doesn't support multiple inheritance. Your derived classes can have only one CObject base class, and that CObject must be leftmost in the hierarchy. It's permissible, however, to have structures and non- CObject-derived classes in right-hand multiple-inheritance branches.

You'll realize major benefits from CObject derivation if you use some of the optional macros in your class implementation and declarations.

The first-level macros, DECLARE_DYNAMIC and IMPLEMENT_DYNAMIC, permit run-time access to the class name and its position in the hierarchy. This, in turn, allows meaningful diagnostic dumping.

The second-level macros, DECLARE_SERIAL and IMPLEMENT_SERIAL, include all the functionality of the first-level macros, and they enable an object to be "serialized" to and from an "archive."

For information about deriving Microsoft Foundation classes and C++ classes in general and using CObject, see Using CObject and Serialization.

Inheritance Hierarchy

CObject

Requirements

Header: afx.h

CObject::AssertValid

Validates this object's integrity.

virtual void AssertValid() const;

Remarks

AssertValid performs a validity check on this object by checking its internal state. In the Debug version of the library, AssertValid may assert and then terminate the program with a message that lists the line number and filename where the assertion failed.

When you write your own class, you should override the AssertValid function to provide diagnostic services for yourself and other users of your class. The overridden AssertValid usually calls the AssertValid function of its base class before checking data members unique to the derived class.

Because AssertValid is a const function, you aren't permitted to change the object state during the test. Your own derived class AssertValid functions shouldn't throw exceptions but rather should assert whether they detect invalid object data.

The definition of "validity" depends on the object's class. As a rule, the function should do a "shallow check." That is, if an object contains pointers to other objects, it should check to see whether the pointers aren't NULL, but it shouldn't do validity testing on the objects referred to by the pointers.

Example

See CObList::CObList for a listing of the CAge class used in all CObject examples.

void CAge::AssertValid() const
{
   CObject::AssertValid();
   ASSERT(m_years > 0); 
   ASSERT(m_years < 105);
}

For another example, see AfxDoForAllObjects.

CObject::CObject

These functions are the standard CObject constructors.

CObject();
CObject(const CObject& objectSrc);

Parameters

objectSrc
A reference to another CObject

Remarks

The default version is automatically called by the constructor of your derived class.

If your class is serializable (it incorporates the IMPLEMENT_SERIAL macro), then you must have a default constructor (a constructor with no arguments) in your class declaration. If you don't need a default constructor, declare a private or protected "empty" constructor. For more information, see Using CObject.

The standard C++ default class copy constructor does a member-by-member copy. The presence of the private CObject copy constructor guarantees a compiler error message if the copy constructor of your class is needed but not available. Provide a copy constructor if your class requires this capability.

Example

See CObList::CObList for a listing of the CAge class used in the CObject examples.

// Create a CAge object using the default constructor.
CAge age1;

// Create a CAge object using the copy constructor.
CAge age2(age1);

CObject::Dump

Dumps the contents of your object to a CDumpContext object.

virtual void Dump(CDumpContext& dc) const;

Parameters

dc
The diagnostic dump context for dumping, usually afxDump.

Remarks

When you write your own class, you should override the Dump function to provide diagnostic services for yourself and other users of your class. The overridden Dump usually calls the Dump function of its base class before printing data members unique to the derived class. CObject::Dump prints the class name if your class uses the IMPLEMENT_DYNAMIC or IMPLEMENT_SERIAL macro.

Note

Your Dump function shouldn't print a newline character at the end of its output.

Dump calls make sense only in the Debug version of the Microsoft Foundation Class Library. You should bracket calls, function declarations, and function implementations with #ifdef _DEBUG, #endif statements for conditional compilation.

Since Dump is a const function, you aren't permitted to change the object state during the dump.

The CDumpContext insertion (<<) operator calls Dump when a CObject pointer is inserted.

Dump permits only "acyclic" dumping of objects. You can dump a list of objects, for example, but if one of the objects is the list itself, you'll eventually overflow the stack.

Example

See CObList::CObList for a listing of the CAge class used in all CObject examples.

void CAge::Dump(CDumpContext& dc) const
{
   CObject::Dump(dc);
   dc << _T("Age = ") << m_years;
}

CObject::GetRuntimeClass

Returns the CRuntimeClass structure corresponding to this object's class.

virtual CRuntimeClass* GetRuntimeClass() const;

Return Value

A pointer to the CRuntimeClass structure corresponding to this object's class; never NULL.

Remarks

There's one CRuntimeClass structure for each CObject-derived class. The structure members are as follows:

  • LPCSTR m_lpszClassName A null-terminated string containing the ASCII class name.

  • int m_nObjectSize The size of the object, in bytes. If the object has data members that point to allocated memory, the size of that memory isn't included.

  • UINT m_wSchema The schema number ( -1 for nonserializable classes). See the IMPLEMENT_SERIAL macro for a description of schema number.

  • CObject* (PASCAL* m_pfnCreateObject)() A function pointer to the default constructor that creates an object of your class (valid only if the class supports dynamic creation; otherwise, returns NULL).

  • CRuntimeClass* (PASCAL* m_pfn_GetBaseClass )() If your application is dynamically linked to the AFXDLL version of MFC, a pointer to a function that returns the CRuntimeClass structure of the base class.

  • CRuntimeClass* m_pBaseClass If your application is statically linked to MFC, a pointer to the CRuntimeClass structure of the base class.

This function requires use of the IMPLEMENT_DYNAMIC, IMPLEMENT_DYNCREATE, or IMPLEMENT_SERIAL macro in the class implementation. You'll get incorrect results otherwise.

Example

See CObList::CObList for a listing of the CAge class used in all CObject examples.

CAge a(21);
CRuntimeClass* prt = a.GetRuntimeClass();
ASSERT(strcmp(prt->m_lpszClassName, "CAge") == 0);

CObject::IsKindOf

Tests this object's relationship to a given class.

BOOL IsKindOf(const CRuntimeClass* pClass) const;

Parameters

pClass
A pointer to a CRuntimeClass structure associated with your CObject-derived class.

Return Value

Nonzero if the object corresponds to the class; otherwise 0.

Remarks

This function tests pClass to see if (1) it's an object of the specified class or (2) it's an object of a class derived from the specified class. This function works only for classes declared with the DECLARE_DYNAMIC, DECLARE_DYNCREATE, or DECLARE_SERIAL macro.

Don't use this function extensively because it defeats the C++ polymorphism feature. Use virtual functions instead.

Example

See CObList::CObList for a listing of the CAge class used in all CObject examples.

CAge a(21);  // Must use IMPLEMENT_DYNAMIC, IMPLEMENT _DYNCREATE, or
             // IMPLEMENT_SERIAL
ASSERT(a.IsKindOf(RUNTIME_CLASS(CAge)));
ASSERT(a.IsKindOf(RUNTIME_CLASS(CObject)));

CObject::IsSerializable

Tests whether this object is eligible for serialization.

BOOL IsSerializable() const;

Return Value

Nonzero if this object can be serialized; otherwise 0.

Remarks

For a class to be serializable, its declaration must contain the DECLARE_SERIAL macro, and the implementation must contain the IMPLEMENT_SERIAL macro.

Note

Don't override this function.

Example

See CObList::CObList for a listing of the CAge class used in all CObject examples.

CAge a(21);
ASSERT(a.IsSerializable());

CObject::operator delete

For the Release version of the library, operator delete frees the memory allocated by operator new.

void PASCAL operator delete(void* p);

void PASCAL operator delete(
    void* p,
    void* pPlace);

void PASCAL operator delete(
    void* p,
    LPCSTR lpszFileName,
    int nLine);

Remarks

In the Debug version, operator delete participates in an allocation-monitoring scheme designed to detect memory leaks.

If you use the code line

#define new DEBUG_NEW

before any of your implementations in a .CPP file, then the third version of delete will be used, storing the filename and line number in the allocated block for later reporting. You don't have to worry about supplying the extra parameters; a macro takes care of that for you.

Even if you don't use DEBUG_NEW in Debug mode, you still get leak detection, but without the source-file line-number reporting described above.

If you override operators new and delete, you forfeit this diagnostic capability.

Example

See CObList::CObList for a listing of the CAge class used in the CObject examples.

void CAge::operator delete(void* p)
{
   free(p);
}

void CAge::operator delete(void *p, LPCSTR lpszFileName, int nLine)
{
   UNREFERENCED_PARAMETER(lpszFileName);
   UNREFERENCED_PARAMETER(nLine);
   free(p);
}

CObject::operator new

For the Release version of the library, operator new does an optimal memory allocation in a manner similar to malloc.

void* PASCAL operator new(size_t nSize);
void* PASCAL operator new(size_t, void* p);

void* PASCAL operator new(
    size_t nSize,
    LPCSTR lpszFileName,
    int nLine);

Remarks

In the Debug version, operator new participates in an allocation-monitoring scheme designed to detect memory leaks.

If you use the code line

#define new DEBUG_NEW

before any of your implementations in a .CPP file, then the second version of new will be used, storing the filename and line number in the allocated block for later reporting. You don't have to worry about supplying the extra parameters; a macro takes care of that for you.

Even if you don't use DEBUG_NEW in Debug mode, you still get leak detection, but without the source-file line-number reporting described above.

Note

If you override this operator, you must also override delete. Don't use the standard library _new_handler function.

Example

See CObList::CObList for a listing of the CAge class used in the CObject examples.

void* CAge::operator new(size_t nSize)
{
   return malloc(nSize);
}

void* CAge::operator new(size_t nSize, LPCSTR lpszFileName, int nLine)
{
   UNREFERENCED_PARAMETER(lpszFileName);
   UNREFERENCED_PARAMETER(nLine);
   return malloc(nSize);
}

CObject::Serialize

Reads or writes this object from or to an archive.

virtual void Serialize(CArchive& ar);

Parameters

ar
A CArchive object to serialize to or from.

Remarks

Override Serialize for each class that you intend to serialize. The overridden Serialize must first call the Serialize function of its base class.

You must also use the DECLARE_SERIAL macro in your class declaration, and you must use the IMPLEMENT_SERIAL macro in the implementation.

Use CArchive::IsLoading or CArchive::IsStoring to determine whether the archive is loading or storing.

Serialize is called by CArchive::ReadObject and CArchive::WriteObject. These functions are associated with the CArchive insertion operator ( <<) and extraction operator ( >>).

For serialization examples, see the article Serializing an Object.

Example

See CObList::CObList for a listing of the CAge class used in all CObject examples.

void CAge::Serialize(CArchive& ar)
{
   CObject::Serialize(ar);
   if(ar.IsStoring())
      ar << m_years;
   else
      ar >> m_years;
}

See also

Hierarchy Chart