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 theIMPLEMENT_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, returnsNULL
).CRuntimeClass* (PASCAL* m_pfn_GetBaseClass )()
If your application is dynamically linked to the AFXDLL version of MFC, a pointer to a function that returns theCRuntimeClass
structure of the base class.CRuntimeClass* m_pBaseClass
If your application is statically linked to MFC, a pointer to theCRuntimeClass
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;
}