CObject
类
Microsoft 基础类库中的主体基类。
语法
class AFX_NOVTABLE CObject
成员
受保护构造函数
名称 | 描述 |
---|---|
CObject::CObject |
默认构造函数。 |
公共方法
名称 | 描述 |
---|---|
CObject::AssertValid |
验证此对象的完整性。 |
CObject::Dump |
生成此对象的诊断转储。 |
CObject::GetRuntimeClass |
返回与此对象的类对应的 CRuntimeClass 结构。 |
CObject::IsKindOf |
测试此对象与给定类的关系。 |
CObject::IsSerializable |
测试以查看是否可以序列化此对象。 |
CObject::Serialize |
从/向存档加载或存储对象。 |
公共运算符
“属性” | 描述 |
---|---|
CObject::operator delete |
特殊 delete 运算符。 |
CObject::operator new |
特殊 new 运算符。 |
备注
它不仅用作库类(例如 CFile
和 CObList
)的根,而且还用作所写入的类的根。 CObject
提供基本服务,包括
- 序列化支持
- 运行时类信息
- 对象诊断输出
- 与集合类的兼容性
CObject
不支持多重继承。 派生的类只能有一个 CObject
基类,并且该 CObject
必须位于层次结构中的最左侧。 但是,允许结构和非 CObject
派生类位于右侧多重继承分支中。
如果在类实现和声明中使用一些可选宏,你将从 CObject
派生中获得重大好处。
第一级宏 DECLARE_DYNAMIC
和 IMPLEMENT_DYNAMIC
允许运行时访问类名及其在层次结构中的位置。 这反过来又允许有意义的诊断转储。
第二级宏 DECLARE_SERIAL
和 IMPLEMENT_SERIAL
包括第一级宏的所有功能,它们使对象能够“序列化”为“存档”,以及能够从“存档”“序列化”对象。
有关常规派生 Microsoft 基础类和 C++ 类以及使用 CObject
的信息,请参阅使用 CObject 和序列化。
继承层次结构
CObject
要求
标头:afx.h
CObject::AssertValid
验证此对象的完整性。
virtual void AssertValid() const;
备注
AssertValid
通过检查此对象的内部状态对其执行验证检查。 在库的调试版本中,AssertValid
可以断言,然后终止程序,并显示一条消息,其中列出了断言失败的行号和文件名。
当编写自己的类时,应替代 AssertValid
函数,以便为你自己和你的类的其他用户提供诊断服务。 替代的 AssertValid
通常在检查派生类唯一的数据成员之前调用其基类的 AssertValid
函数。
由于 AssertValid
是 const
函数,因此在测试期间不允许更改对象状态。 你自己的派生类 AssertValid
函数不应引发异常,而是应断言它们是否检测到无效的对象数据。
“有效性”的定义取决于对象的类。 一般来说,函数应执行“浅表检查”。也就是说,如果对象包含指向其他对象的指针,它应检查指针是否不为 NULL
,但它不应对指针所引用的对象执行有效性测试。
示例
有关所有 CObject
示例中使用的 CAge
类的列表,请参阅 CObList::CObList
。
void CAge::AssertValid() const
{
CObject::AssertValid();
ASSERT(m_years > 0);
ASSERT(m_years < 105);
}
若要查看其他示例,请参见AfxDoForAllObjects
。
CObject::CObject
这些函数是标准的 CObject
构造函数。
CObject();
CObject(const CObject& objectSrc);
参数
objectSrc
对另一个 CObject
的引用
备注
派生类的构造函数会自动调用默认版本。
如果类是可序列化的(它包含 IMPLEMENT_SERIAL
宏),则必须在类声明中包含默认构造函数(不带参数的构造函数)。 如果不需要默认构造函数,请声明私有或受保护的“空”构造函数。 有关详细信息,请参阅使用 CObject
。
标准 C++ 默认类复制构造函数执行逐个成员复制。 当需要类的复制构造函数但又不可用时,私有 CObject
复制构造函数的存在可保证出现编译器错误消息。 如果类需要此功能,请提供复制构造函数。
示例
有关 CObject
示例中使用的 CAge
类的列表,请参阅 CObList::CObList
。
// Create a CAge object using the default constructor.
CAge age1;
// Create a CAge object using the copy constructor.
CAge age2(age1);
CObject::Dump
将对象的内容转储到 CDumpContext
对象。
virtual void Dump(CDumpContext& dc) const;
参数
dc
用于转储的诊断转储上下文,通常为 afxDump
。
备注
当编写自己的类时,应替代 Dump
函数,以便为你自己和你的类的其他用户提供诊断服务。 替代的 Dump
通常在打印派生类唯一的数据成员之前调用其基类的 Dump
函数。 如果类使用 IMPLEMENT_DYNAMIC
或 IMPLEMENT_SERIAL
宏,则 CObject::Dump
会打印类名。
注意
Dump
函数不应在其输出末尾打印换行符。
Dump
调用仅在调试版本的 Microsoft 基础类库中有意义。 应使用 #ifdef _DEBUG
和 #endif
语句将调用、函数声明和函数实现括起来,用于条件编译。
由于 Dump
是 const
函数,因此在转储期间不允许更改对象状态。
当插入 CObject
指针时,CDumpContext
插入 (<<) 运算符会调用 Dump
。
Dump
仅允许对象的“非循环”转储。 例如,可以转储对象列表,但如果其中一个对象是列表本身,最终将溢出堆栈。
示例
有关所有 CObject
示例中使用的 CAge
类的列表,请参阅 CObList::CObList
。
void CAge::Dump(CDumpContext& dc) const
{
CObject::Dump(dc);
dc << _T("Age = ") << m_years;
}
CObject::GetRuntimeClass
返回与此对象的类对应的 CRuntimeClass
结构。
virtual CRuntimeClass* GetRuntimeClass() const;
返回值
指向对应于此对象的类的 CRuntimeClass
结构的指针;绝不返回 NULL
。
备注
每个 CRuntimeClass
派生类都有一个 CObject
结构。 结构成员如下所示:
LPCSTR m_lpszClassName
包含 ASCII 类名的以 null 结尾的字符串。int m_nObjectSize
对象大小(以字节为单位)。 如果对象具有指向已分配内存的数据成员,则不包括该内存的大小。UINT m_wSchema
架构编号(-1 表示不可序列化的类)。 有关架构编号的说明,请参阅IMPLEMENT_SERIAL
宏。CObject* (PASCAL* m_pfnCreateObject)()
指向创建类对象的默认构造函数的函数指针(仅当类支持动态创建时有效;否则将返回NULL
)。CRuntimeClass* (PASCAL* m_pfn_GetBaseClass )()
如果应用程序动态链接到 AFXDLL 版本的 MFC,则为指向返回基类的CRuntimeClass
结构的函数的指针。CRuntimeClass* m_pBaseClass
如果应用程序静态链接到 MFC,则为指向基类的CRuntimeClass
结构的指针。
此函数要求在类实现中使用 IMPLEMENT_DYNAMIC
、IMPLEMENT_DYNCREATE
或 IMPLEMENT_SERIAL
宏。 否则会得到错误结果。
示例
有关所有 CObject
示例中使用的 CAge
类的列表,请参阅 CObList::CObList
。
CAge a(21);
CRuntimeClass* prt = a.GetRuntimeClass();
ASSERT(strcmp(prt->m_lpszClassName, "CAge") == 0);
CObject::IsKindOf
测试此对象与给定类的关系。
BOOL IsKindOf(const CRuntimeClass* pClass) const;
参数
pClass
指向与 CObject
派生类关联的 CRuntimeClass
结构的指针。
返回值
如果对象对应于类,则为非零值;否则为 0。
备注
此函数测试 pClass
(1) 是指定类的对象 (2) 还是派生自指定类的类的对象。 此函数仅适用于使用 DECLARE_DYNAMIC
、DECLARE_DYNCREATE
或 DECLARE_SERIAL
宏声明的类。
请勿广泛使用此函数,因为它会破坏 C++ 多形性功能。 请改用虚拟函数。
示例
有关所有 CObject
示例中使用的 CAge
类的列表,请参阅 CObList::CObList
。
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
测试此对象是否符合序列化条件。
BOOL IsSerializable() const;
返回值
如果可以序列化此对象,则为非零值;否则为 0。
注解
若要使类可序列化,它的声明必须包含 DECLARE_SERIAL
宏,并且实现必须包含 IMPLEMENT_SERIAL
宏。
注意
请勿替代此函数。
示例
有关所有 CObject
示例中使用的 CAge
类的列表,请参阅 CObList::CObList
。
CAge a(21);
ASSERT(a.IsSerializable());
CObject::operator delete
在库的发布版本中,运算符 delete
释放由运算符 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);
注解
在调试版本中,运算符 delete
参与旨在检测内存泄漏的分配监视方案。
如果使用代码行
#define new DEBUG_NEW
在 .CPP 文件中的任何实现之前使用,则将使用 delete
的第三个版本,这会将文件名和行号存储在分配的块中,供以后报告使用。 无需担心要提供额外的参数;宏会为你解决这一问题。
即使未在调试模式下使用 DEBUG_NEW
,仍会进行泄漏检测,但没有上述的源文件行号报告。
如果替代运算符 new
和 delete
,则将放弃此诊断功能。
示例
有关 CObject
示例中使用的 CAge
类的列表,请参阅 CObList::CObList
。
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
在库的发布版本中,运算符 new
以类似于 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);
备注
在调试版本中,运算符 new
参与旨在检测内存泄漏的分配监视方案。
如果使用代码行
#define new DEBUG_NEW
在 .CPP 文件中的任何实现之前使用,则将使用 new
的第二个版本,这会将文件名和行号存储在分配的块中,供以后报告使用。 无需担心要提供额外的参数;宏会为你解决这一问题。
即使未在调试模式下使用 DEBUG_NEW
,仍会进行泄漏检测,但没有上述的源文件行号报告。
注意
如果替代此运算符,还必须替代 delete
。 请勿使用标准库 _new_handler
函数。
示例
有关 CObject
示例中使用的 CAge
类的列表,请参阅 CObList::CObList
。
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
从存档读取该对象或将该对象写入存档。
virtual void Serialize(CArchive& ar);
参数
ar
要序列化为它或从它进行序列化的 CArchive
对象。
注解
为要序列化的每个类替代 Serialize
。 替代的 Serialize
必须首先调用其基类的 Serialize
函数。
你还需要在类声明中使用 DECLARE_SERIAL
宏,并且必须在实现中使用 IMPLEMENT_SERIAL
宏。
使用 CArchive::IsLoading
或 CArchive::IsStoring
以确定是否正在加载或存储存档。
Serialize
由 CArchive::ReadObject
和 CArchive::WriteObject
调用。 这些函数与 CArchive
插入运算符 (<<
) 和提取运算符 (>>
) 相关联。
有关序列化示例,请参阅序列化对象一文。
示例
有关所有 CObject
示例中使用的 CAge
类的列表,请参阅 CObList::CObList
。
void CAge::Serialize(CArchive& ar)
{
CObject::Serialize(ar);
if(ar.IsStoring())
ar << m_years;
else
ar >> m_years;
}