初学MFC,一个符号的疑惑 mfcc++符号 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 跟文件的写入、读取流一样?这里的“<<” 和 ">>"是不是重写了的呢? CArchive类重载了operator << 和operator <<操作符 CArchive我貌似还没有用过... 对的,<< 和 >> 本是 C++ 里面的 插入操作符 和 提取操作符 。插入操作符 << 的作用是将它后面的内容插入到标准输出流中以便输出,而提取操作符 >> 的作用是从标准输入流中提取数据并存储到它后面的变量中。根据我的理解,所谓输入,就是程序运行的时候,从程序的外部拿数据进来使之成为程序自己的东西;所谓输出,就是程序运行的时候,把程序自己的数据送给外部以供外部来使用。下面的一段 C++ 代码说明了这两个操作符的用法:#include <iostream.h>void main(){ int a; cout<<"Please enter an integer:\n"; cin>>a; cout<<"a: "<<a<<endl;}再来说说你的这个代码:void CScribDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) //如果是在存储归档文件(也就是把数据存储到文档中) ar << m_sizeDoc; //那么就将 m_sizeDoc 变量插入输出流中。这里输出流对象是 CArchive 类的对象 ar ,并且通常情况下 ar 已经和某个特定的文档关联起来了,那么将变量插入输出流中,就是将变量的值写入文档 else //如果当前是在读取归档文件(也就是从文档中读取数据) ar >> m_sizeDoc; //同上。这里输入流对象是 ar ,那么就是从 ar 中提取数据并将数据保存到 m_sizeDoc 变量中 m_graphList.Serialize(ar); //调用 m_graphList 的 Serialize 函数 } 跟文件的写入、读取流一样?这里的“<<” 和 ">>"是不是重写了的呢?3楼说对了,就是重载了那两个符号,不过使用时候要注意写入顺序和读取顺序一致才行。 为此 MFC 的 CArchive 类重载了 << 和 >> 这两个操作符:为了让自定义类能够有永久保存功能,需要重载 << 和 >> 操作符,及其对serialize函数的重写,因此定义了宏DECLARE_SERIAL/IMPLEMENT_SERIAL#define DECLARE_SERIAL(class_name) \ _DECLARE_DYNCREATE(class_name) \ AFX_API friend CArchive& AFXAPI operator >>(CArchive& ar, class_name* &pOb); //友元函数重载>>操作符 #define IMPLEMENT_SERIAL(class_name, base_class_name, wSchema) \ CObject* PASCAL class_name::CreateObject() \ { return new class_name; } \ extern AFX_CLASSINIT _init_##class_name; \ _IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, \ class_name::CreateObject, &_init_##class_name) \ AFX_CLASSINIT _init_##class_name(RUNTIME_CLASS(class_name)); \ CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb) \ { pOb = (class_name*) ar.ReadObject(RUNTIME_CLASS(class_name)); \ return ar; } \为了在每一个对象被处理(读或写)之前,能够处理琐屑的工作,诸如判断是否是第一次出现、记录版本号码、记录文件名等工作,CRuntimeClass结构需要2个函数Load和Store:struct CRuntimeClass{// Attributes LPCSTR m_lpszClassName; int m_nObjectSize; UINT m_wSchema; // schema number of the loaded class CObject* (PASCAL* m_pfnCreateObject)(); // NULL => abstract class#ifdef _AFXDLL CRuntimeClass* (PASCAL* m_pfnGetBaseClass)();#else CRuntimeClass* m_pBaseClass;#endif// Operations CObject* CreateObject(); BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const; // dynamic name lookup and creation static CRuntimeClass* PASCAL FromName(LPCSTR lpszClassName); static CRuntimeClass* PASCAL FromName(LPCWSTR lpszClassName); static CObject* PASCAL CreateObject(LPCSTR lpszClassName); static CObject* PASCAL CreateObject(LPCWSTR lpszClassName);// Implementation void Store(CArchive& ar) const;//存储类名称 static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwSchemaNum);//读取类名称 // CRuntimeClass objects linked together in simple list CRuntimeClass* m_pNextClass; // linked list of registered classes const AFX_CLASSINIT* m_pClassInit;}; CRuntimeClass* PASCAL CRuntimeClass::Load(CArchive& ar, UINT* pwSchemaNum){ WORD nLen; char szClassName[64]; CRuntimeClass* pClass; ar >> (WORD&)(*pwSchemaNum) >> nLen; if(nLen >= sizeof(szClassName) || ar.Read(szClassName, nLen) != nLen ) return NULL; szClassName[nLen] = '\0'; for(pClass = pFirstClass; pClass != NULL; pClass = pClass->m_pNextClass) { if(llstrcmp(szClassName,pClass->m_lpszClassName) == 0) return pClass; } return NULL;}void CRuntimeClass::Store(CArchive& ar) const{ WORD nLen = (WORD)lstrlenA(m_lpszClassName); ar << (WORD)m_wSchema << nLen; ar.Write(m_lpszClassName, nLen*sizeof(char));} CArchive重写了这两个操作符。 拆分视图,怎么样让其中一个视图全屏显示 在哪里找到strsafe.h 求教如何在对话框中加入菜单和弹出菜单 SCSI 设备命令的探测 谁有 win32多线程程序设计 的附书源代码? 请教:单打按钮后自动打开IE并指向某个登陆页面,更重要的是,它需要自动传递用户名和密码完成登陆工作。 Help!目录压缩问题 Basic question when Build a program 如何实现对局域网中其他机器是否上网的状态显示 如何调用MSCOMM控件对串口进行操作 这算是一个BUG吗?VS2010 无法打开Manage Help Settings 管理帮助设定 有谁知道原始套接字是什么?
CArchive我貌似还没有用过...
插入操作符 << 的作用是将它后面的内容插入到标准输出流中以便输出,而提取操作符 >> 的作用是从标准输入流中提取数据并存储到它后面的变量中。
根据我的理解,
所谓输入,就是程序运行的时候,从程序的外部拿数据进来使之成为程序自己的东西;
所谓输出,就是程序运行的时候,把程序自己的数据送给外部以供外部来使用。
下面的一段 C++ 代码说明了这两个操作符的用法:#include <iostream.h>
void main()
{
int a;
cout<<"Please enter an integer:\n";
cin>>a;
cout<<"a: "<<a<<endl;
}再来说说你的这个代码:
void CScribDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring()) //如果是在存储归档文件(也就是把数据存储到文档中)
ar << m_sizeDoc; //那么就将 m_sizeDoc 变量插入输出流中。这里输出流对象是 CArchive 类的对象 ar ,并且通常情况下 ar 已经和某个特定的文档关联起来了,那么将变量插入输出流中,就是将变量的值写入文档
else //如果当前是在读取归档文件(也就是从文档中读取数据)
ar >> m_sizeDoc; //同上。这里输入流对象是 ar ,那么就是从 ar 中提取数据并将数据保存到 m_sizeDoc 变量中
m_graphList.Serialize(ar); //调用 m_graphList 的 Serialize 函数
}
为了让自定义类能够有永久保存功能,需要重载 << 和 >> 操作符,及其对serialize函数的重写,因此定义了宏DECLARE_SERIAL/IMPLEMENT_SERIAL
#define DECLARE_SERIAL(class_name) \
_DECLARE_DYNCREATE(class_name) \
AFX_API friend CArchive& AFXAPI operator >>(CArchive& ar, class_name* &pOb); //友元函数重载>>操作符 #define IMPLEMENT_SERIAL(class_name, base_class_name, wSchema) \
CObject* PASCAL class_name::CreateObject() \
{ return new class_name; } \
extern AFX_CLASSINIT _init_##class_name; \
_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, \
class_name::CreateObject, &_init_##class_name) \
AFX_CLASSINIT _init_##class_name(RUNTIME_CLASS(class_name)); \
CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb) \
{ pOb = (class_name*) ar.ReadObject(RUNTIME_CLASS(class_name)); \
return ar; } \为了在每一个对象被处理(读或写)之前,能够处理琐屑的工作,诸如判断是否是第一次出现、记录版本号码、记录文件名等工作,CRuntimeClass结构需要2个函数Load和Store:struct CRuntimeClass
{
// Attributes
LPCSTR m_lpszClassName;
int m_nObjectSize;
UINT m_wSchema; // schema number of the loaded class
CObject* (PASCAL* m_pfnCreateObject)(); // NULL => abstract class
#ifdef _AFXDLL
CRuntimeClass* (PASCAL* m_pfnGetBaseClass)();
#else
CRuntimeClass* m_pBaseClass;
#endif// Operations
CObject* CreateObject();
BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const; // dynamic name lookup and creation
static CRuntimeClass* PASCAL FromName(LPCSTR lpszClassName);
static CRuntimeClass* PASCAL FromName(LPCWSTR lpszClassName);
static CObject* PASCAL CreateObject(LPCSTR lpszClassName);
static CObject* PASCAL CreateObject(LPCWSTR lpszClassName);// Implementation
void Store(CArchive& ar) const;//存储类名称
static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwSchemaNum);//读取类名称 // CRuntimeClass objects linked together in simple list
CRuntimeClass* m_pNextClass; // linked list of registered classes
const AFX_CLASSINIT* m_pClassInit;
}; CRuntimeClass* PASCAL CRuntimeClass::Load(CArchive& ar, UINT* pwSchemaNum)
{
WORD nLen;
char szClassName[64];
CRuntimeClass* pClass;
ar >> (WORD&)(*pwSchemaNum) >> nLen;
if(nLen >= sizeof(szClassName) || ar.Read(szClassName, nLen) != nLen )
return NULL;
szClassName[nLen] = '\0';
for(pClass = pFirstClass; pClass != NULL; pClass = pClass->m_pNextClass)
{
if(llstrcmp(szClassName,pClass->m_lpszClassName) == 0)
return pClass;
}
return NULL;
}
void CRuntimeClass::Store(CArchive& ar) const
{
WORD nLen = (WORD)lstrlenA(m_lpszClassName);
ar << (WORD)m_wSchema << nLen;
ar.Write(m_lpszClassName, nLen*sizeof(char));
}