declare_serialVC串行化

declare_serial  时间:2021-01-17  阅读:()

db2自定义函数错误

错误信息显示:在函数上下文中,不能使用序列DB2INST1.SEQ_SERIAL。

谁告诉我几个MFC的常用类 谢谢

常用的MFC类 CRuntimeClass结构 在CRuntimeClass构中定义了类名、对象所占存储空间的大小、类的版本号等成员变量及动态创建对象、派生关系判断等成员函数。

每一个从CObject类派生的类都有一个CRuntimeClass结构同它关联,以便完成在运行时得到对象的信息或基类的信息。

要使用CRuntimeClass结构,必须结合使用RUNTIME_CLASS()宏和其他有关运行时类型识别的MFC宏。

CObject类 MFC的CObject类为程序员提供了对象诊断、运行时类型标识和序列化等功能。

(1)对象诊断:利用成员函数AssertValid进行对象有效性检查;利用成员函数Dump输出对象的数据成员的值,诊断信息以文本形式放入一个数据流中,用于调试器的输出窗口信息显示。

(只能用于Debug版的应用程序) (2)运行时类型识别:GetRuntimeClass根据对象的类返回一个相关联的指向CRuntimeClass结构的指针,它包含了一个类的运行信息;函数IsKindOf用于测试对象与给定类的关系。

(3)通过与Carchive相结合,CObject类为其派生类提供了序列化功能。

要创建一个支持序列化的派生类,必须将DECLARE_SERIAL宏添加到类定义中,将IMPLEMENT_SERIAL添加到类的实现文件中。

CCmdTarget类 由CObject类直接派生,所有能实行消息映射MFC类的基类。

功能如下: (1)消息发送 MFC应用程序为每个CCmdTarget派生类创建一个称为消息映射表的静态数据结构,可将消息映射到对象所对应的消息处理函数上。

(2)设置光标 程序正在进行某种操作:BeginWaitCursor()将光标改为沙漏形状; 操作完成:EndWaitCursor()将光标改回到之前的形状; 处于等待状态时由于某些操作改变了光标形状后,RestoreWaitCursor()用于将光标还原为等待状态。

(3)支持自动化 CCmdTarget类支持程序通过COM接口进行交互操作,自动翻译COM接口的方法。

方法是调用EnableAutomation()、FromIDispatch()、GetIDispatch()、IsResultExpected()和 OnFinalRelease()。

CWinThread类 由CCmdTarget派生,主要工作是创建和处理消息循环。

CWinApp类 从CWinThread类派生,成员函数InitApplication()、InitInstance()、Run()。

在MFC应用程序中有且仅有一个CWinApp派生类的对象,代表程序运行的主线程,代表应用程序本身。

CWnd类 由CCmdTarget类直接派生,是MFC中最基本的GUI对象。

公共变量m_hWnd用于存放供API函数调用的窗口句柄。

CframeWnd类 从CWnd类派生而来,主要用来掌管一个窗口。

其对象是一个框架窗口,包括边界、标题栏、菜单、最大化按钮、最小化按钮和一个激活的视图。

其常用成员函数: GetActiveDocument():得到当前文档的指针。

GetActiveView():得到当前视图的指针。

SetActiveView():激活一个视图。

GetTitle():得到框架窗口的标题。

SetTitle():设置框架窗口的标题。

SetMessageText():设置状态栏文本。

CDocument类 从CCmdTarget派生,作为用户文档的基类,代表了用户存储或打开一个文件。

主要功能是把对数据的处理从对用户的界面处理中分离出来,同时提供一个与视图类交互的接口。

常用的成员函数有: OnNewDocument():建立新文档。

OnOpenDocument():打开一个文档。

OnCloseDocument():关闭文档。

OnSaveDocument():保存文档。

UpdateAllView():通知所有视图文档被修改。

SaveModified():设置文档修改标志。

CView类 从CWnd类派生而来,是MFC视图类和用户视图类的基类。

CWnd::Invalidate()或CWnd::InvalidateRect()可以刷新视图。

如何串行化一个类

我们来一起学习学习 一个类能被串行化必须具备的条件是 一下5个 (1) 这个类要从CObject类派生 (2) 覆盖父类的Serialize函数(重载) (3) 使用 宏DECLARE_SERIAL(类名) 将该声明放入该类的类体头文件中 (4) 构造一个该类的不带参数的构造函数 (5) 使用宏IMPLEMENT_SERIAL(类名, CObject, 版本号)声明在cpp文件中,一般情况下 版本号设置为 1 并放到cpp的函数体前 具备上边的条件后就该类就可以被串行化了 说起串行化其实就是将一个类的工作状态的关键的数据保存到文件中 , 等再次打开该文件的时候可以再现原来的工作状态的一个方法 版本号必要要在声明中和读取过程中保持一致 文档类最终保存对象实际上是在调用该类的 Serialize函数来完成 在这里我们要学会使用 CObjectArray类它本身就可以支持串行化 在单文档和多文档中,我们将CObjectArray类的定义放到CDocument类中完成 当用完CObjectArray对象后我们一般可以使用 RemoveAll函数来删除所有元素示例:类中的串行化函数 void CGraph::Serialize(CArchive& ar){if(ar.IsStoring()){ar<<m_nDrawType<<m_ptOrigin<<m_ptEnd;}else{arm_nDrawTypem_ptOriginm_ptEnd;}}在文档类中添加一个成员变量public:CObArray m_obArray; 文档类的串行化函数 void CGraphicDoc::Serialize(CArchive& ar){POSITION pos=GetFirstViewPosition(); CGraphicView *pView=(CGraphicView*)GetNextView(pos); if (ar.IsStoring()){}else{ }m_obArray.Serialize(ar);} 这样你就可以通过CObArray 类的串行化来实现对类的"存储"了,就可以再现当时保存该类的状态了 不过你要在你的 OnDraw函数中重新绘制你保存的数据 不是很难的吧哈哈 又长见识了吧

VC串行化

串行化是微软提供的用于对对象进行文件I/O的一种机制,该机制在框架(Frame)/文档(Document)/视图(View) 模式中得到了很好的应用。

很多人对什么是串行化、怎么使对象具有串行化能力和如何使用串行化功能等问题都不甚明了。

本文试图对串行化做一个简单的解释。

由于本人对串行化功能使用的也不多,不足之处敬请谅解。

MFC 框架/文档/视图结构中的文件读写 CFile是MFC类库中所有文件类的基类。

所有MFC提供的文件I/O功能都和这个类有关。

很多情况下,大家都喜欢直接调用CFile::Write/WriteHuge来写文件,调用CFile::Read/ReadHuge来读文件。

这样的文件I/O其实和不使用MFC的文件 I/O没有什么区别,甚至和以前的ANSI C的文件I/O也没有多少差别,所差别的不外乎是调用的API不同而已。

在开始学习C++的时候,大家一定对cin/cout非常熟悉,这两个对象使用非常明了的<<和>>运算符进行 I/O,其使用格式为: //示例代码1 int i; cin >> i; //here do something to object i cout << i; 使用这种方式进行I/O的好处时,利用运算符重载功能,可以用一个语句完成对一系列的对象的读写,而不需要区分对象具体的类型。

MFC提供了类CArchive,实现了运算符<<和>>的重载,希望按照前面cin和cout 的方式进行文件I/O。

通过和CFile类的配合,不仅仅实现了对简单类型如int/float等的文件读写,而且实现了对可序列化对象(Serializable Objects,这个概念后面描述)的文件读写。

一般情况下,使用CArchive对对象进行读操作的过程如下: //示例代码2 //定义文件对象和文件异常对象 CFile file; CFileException fe; //以读方式打开文件 if(!file.Open(filename,CFile::modeRead,&fe)) { fe.ReportError(); return; } //构建CArchive 对象 CArchive ar(&file,CArchive::load); ar >> obj1>>obj2>>obj3...>>objn; ar.Flush(); //读完毕,关闭文件流 ar.Close(); file.Close(); 使用CArchive对对象进行写操作的过程如下: //示例代码3 //定义文件对象和文件异常对象 CFile file; CFileException fe; //以读方式打开文件 if(!file.Open(filename,CFile::modeWrite|CFile::modeCreate,&fe)) { fe.ReportError(); return; } //构建CArchive 对象 CArchive ar(&file,CArchive::load); ar << obj1<<obj2<<obj3...<<objn; ar.Flush(); //写完毕,关闭文件流 ar.Close(); file.Close(); 可见,对于一个文件而言,如果文件内对象的排列顺序是固定的,那么对于文件读和写从形式上只有使用的运算符的不同。

在MFC的框架/文档/视图结构中,一个文档的内部对象的构成往往是固定的,这种情况下,写到文件中时对象在文件中的布局也是固定的。

因此CDocument利用其基类CObject提供的Serilize虚函数,实现自动文档的读写。

当用户在界面上选择文件菜单/打开文件(ID_FILE_OPEN)时,CWinApp派生类的OnFileOpen函数被自动调用,它通过文档模板创建(MDI)/重用(SDI)框架、文档和视图对象,并最终调用CDocument::OnOpenDocument来读文件,CDocument::OnOpenDocument 的处理流程如下: //示例代码4 BOOL CDocument::OnOpenDocument(LPCTSTR lpszPathName) { if (IsModified()) TRACE0("Warning: OnOpenDocument replaces an unsaved document. "); CFileException fe; CFile* pFile = GetFile(lpszPathName, CFile::modeRead|CFile::shareDenyWrite, &fe); if (pFile == NULL) { ReportSaveLoadException(lpszPathName, &fe, FALSE, AFX_IDP_FAILED_TO_OPEN_DOC); return FALSE; } DeleteContents(); SetModifiedFlag(); // dirty during de-serialize CArchive loadArchive(pFile, CArchive::load | CArchive::bNoFlushOnDelete); loadArchive.m_pDocument = this; loadArchive.m_bForceFlat = FALSE; TRY { CWaitCursor wait; if (pFile->GetLength() != 0) Serialize(loadArchive); // load me loadArchive.Close(); ReleaseFile(pFile, FALSE); } CATCH_ALL(e) { ReleaseFile(pFile, TRUE); DeleteContents(); // remove failed contents TRY { ReportSaveLoadException(lpszPathName, e, FALSE, AFX_IDP_FAILED_TO_OPEN_DOC); } END_TRY DELETE_EXCEPTION(e); return FALSE; } END_CATCH_ALL SetModifiedFlag(FALSE); // start off with unmodified return TRUE; } 同样,当用户选择菜单文件/文件保存(ID_FILE_SAVE)或者文件/另存为...(ID_FILE_SAVEAS)时,通过CWinApp::OnFileSave和CWinApp::OnFileSaveAs 最终调用CDocument::OnSaveDocument,这个函数处理如下: //示例代码5 BOOL CDocument::OnSaveDocument(LPCTSTR lpszPathName) { CFileException fe; CFile* pFile = NULL; pFile = GetFile(lpszPathName, CFile::modeCreate | CFile::modeReadWrite | CFile::shareExclusive, &fe); if (pFile == NULL) { ReportSaveLoadException(lpszPathName, &fe, TRUE, AFX_IDP_INVALID_FILENAME); return FALSE; } CArchive saveArchive(pFile, CArchive::store | CArchive::bNoFlushOnDelete); saveArchive.m_pDocument = this; saveArchive.m_bForceFlat = FALSE; TRY { CWaitCursor wait; Serialize(saveArchive); // save me saveArchive.Close(); ReleaseFile(pFile, FALSE); } CATCH_ALL(e) { ReleaseFile(pFile, TRUE); TRY { ReportSaveLoadException(lpszPathName, e, TRUE, AFX_IDP_FAILED_TO_SAVE_DOC); } END_TRY DELETE_EXCEPTION(e); return FALSE; } END_CATCH_ALL SetModifiedFlag(FALSE); // back to unmodified return TRUE; // ess } 从前面两段代码可以看出,文件读和文件写的结构基本相同,并且最终都调用了CObject::Serialize函数完成对文档自己的读和写(参见注释中的save me和load me)。

对于用AppWizard自动生成的MDI和SDI,系统自动生成了这个函数的重载实现,缺省的实现为: //示例代码6 void CMyDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // TODO: add storing code here } else { // TODO: add loading code here } } 如果一个对VC非常熟悉的人,喜欢手工生成所有的代码(当然这是非常浪费时间也是没有必要的),那么他提供的CDocument派生类也应该实现这个缺省的Serialize函数,否则,系统在文件读写时只能调用CObject::Serialize,这个函数什么都不做,当然也无法完成对特定对象的文件保存/载入工作。

当然,用户也可以截获ID_FILE_OPEN等菜单,实现自己的文件读写功能,但是这样的代码将变得非常烦琐,也不容易阅读。

回到CMyDoc::Serialize函数。

这个函数通过对ar对象的判断,决定当前是在读还是在写文件。

由于AppWizard不知道你的文档是干什么的,所以它不会给你添加实际的文件读写代码。

假设你的文档中有三个对象m_Obj_a,m_Obj_b,m_Obj_c,那么实际的代码应该为: //示例代码7 void CMyDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { ar << m_Obj_a << m_Obj_b << m_Obj_c; } else { ar >> m_Obj_a >> m_Obj_b >> m_Obj_c; } } 可串行化对象(Serializable Object) 要利用示例代码7中的方式进行文件I/O的一个基本条件是:m_Obj_a等对象必须是可串行化的对象。

一个可串行化对象的条件为: 这个类从CObject派生) 该类实现了Serialize函数 该类在定义时使用了DECLARE_SERIAL宏 在类的实现文件中使用了IMPLEMENT_SERIAL宏 这个类有一个不带参数的构造函数,或者某一个带参数的构造函数所有的参数都提供了缺省参数 这里,可串行化对象条件中没有包括简单类型,对于简单类型,CArchive基本都实现了运算符<<和>>的重载,所以可以直接使用串行化方式进行读写。

从CObject类派生 串行化要求对象从CObject派生,或者从一个CObject的派生类派生。

这个要求比较简单,因为几乎所有的类(不包括CString)都是从CObject 派生的,因此对于从MFC类继承的类都满足这个要求。

对于自己的数据类,可以指定它的基类为CObject来满足这个要求。

实现Serialize函数 Serialize函数是对象真正保存数据的函数,是整个串行化的核心。

其实现方法和CMyDoc::Serialize一样,利用CArchive::IsStoring和CArchive::IsLoading 判断当前的操作,并选择<<和>>来保存和读取对象。

使用DECLARE_SERIAL宏 DECLARE_SERIAL宏包括了DECLARE_DYNAMIC和DECLARE_DYNCREATE功能,它定义了一个类的CRuntimeClass相关信息,并实现了缺省的operator >> 重载。

实现了该宏以后,CArchive就可以利用ReadObject和WriteObject来进行对象I/O,并能够在事先不知道类型的情况下从文件中读对象。

使用IMPLEMENT_SERIAL DECLARE_SERIAL宏和IMPLEMENT_SERIAL宏必须成对出现,否则DECLARE_SERIAL宏定义的实体将无法实现,最终导致连接错误。

缺省构造函数 这是CRuntimeClass::CreateObject对对象的要求。

特殊情况 只通过Serialize函数对对象读写,而不使用ReadObject/WriteObject和运算符重载时,前面的可串行化条件不需要,只要实现Serialize 函数即可。

对于现存的类,如果它没有提供串行化功能,可以通过使用重载友元operator <<和operator >>来实现。

例子 假设需要实现一个几何图形显示、编辑程序,支持可扩展的图形功能。

这里不想讨论具体图形系统的实现,只讨论图像对象的保存和载入。

基类CPicture 每个图形对象都从CPicture派生,这个类实现了串行化功能,其实现代码为: //头文件picture.h #if !defined(__PICTURE_H__) #define __PICTURE_H__ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 const int TYPE_UNKNOWN = -1; class CPicture:public CObject { int m_nType;//图形类别 DECLARE_SERIAL(CPicture) public: CPicture(int m_nType=TYPE_UNKNOWN):m_nType(m_nType){}; int GetType()const {return m_nType;}; virtual void Draw(CDC * pDC); void Serialize(CArchive & ar); }; #endif //cpp文件picture.cpp #include "stdafx.h" #include "picture.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif void CPicture::Draw(CDC * pDC) { //基类不实现绘图功能,由派生类实现 } void CPicture::Serialize(CArchive & ar) { if(ar.IsLoading()) { ar << m_nType; }else{ ar >> m_nType; } } 注意:由于CRuntimeClass要求这个对象必须能够被实例化,因此虽然Draw函数没有任何绘图操作,这个类还是没有把它定义成纯虚函数。

对象在CDocument派生类中的保存和文件I/O过程 为了简化设计,在CDocument类派生类中,采用MFC提供的模板类CPtrList来保存对象。

该对象定义为: protected: CTypedPtrList m_listPictures; 由于CTypedPtrList和CPtrList都没有实现Serialize函数,因此不能够通过ar << m_listPictures和ar >> m_listPictures 来序列化对象,因此CPictureDoc的Serialize函数需要如下实现: void CTsDoc::Serialize(CArchive& ar) { POSITION pos; if (ar.IsStoring()) { // TODO: add storing code here pos = m_listPictures.GetHeadPosition(); while(pos != NULL) { ar << m_listPictures.GetNext (pos); } } else { // TODO: add loading code here RemoveAll(); CPicture * pPicture; do{ try { ar >> pPicture; TRACE("Read Object %d ",pPicture->GetType ()); m_listPictures.AddTail(pPicture); } catch(CException * e) { e->Delete (); break; } }while(pPicture != NULL); } m_pCurrent = NULL; SetModifiedFlag(FALSE); } 实现派生类的串行化功能 几何图形程序支持直线、矩形、三角形、椭圆等图形,分别以类CLine、CRectangle、CTriangle和CEllipse实现。

以类CLine为例,实现串行化功能: 从CPicture派生CLine,在CLine类定义中增加如下成员变量: CPoint m_ptStart,m_ptEnd; 在该行下一行增加如下宏: DECLARE_SERIAL(CLine) 实现Serialize函数 void CLine::Serialize(CArchive & ar) { CPicture::Serialize(ar); if(ar.IsLoading()) { ar>>m_ptStart.x>>m_ptStart.y>>m_ptEnd.x>>m_ptEnd.y; }else{ ar<<m_ptStart.x<<m_ptStart.y<<m_ptEnd.x<<m_ptEnd.y; } } 在CPP文件中增加 IMPLEMENT_SERIAL(CLine,CPicture,TYPE_LINE); 这样定义的CLine就具有串行化功能,其他图形类可以类似定义。

RAKsmart含站群服务器/10G带宽不限流量首月半价

RAKsmart 商家估摸着前段时间服务器囤货较多,这两个月的促销活动好像有点针对独立服务器。前面才整理到七月份的服务器活动在有一些配置上比上个月折扣力度是大很多,而且今天看到再来部分的服务器首月半价,一般这样的促销有可能是商家库存充裕。比如近期有一些服务商挖矿服务器销售不好,也都会采用这些策略,就好比电脑硬件最近也有下降。不管如何,我们选择服务器或者VPS主机要本着符合自己需求,如果业务不需要,...

6元虚拟主机是否值得购买

6元虚拟主机是否值得购买?近期各商家都纷纷推出了优质便宜的虚拟主机产品,其中不少6元的虚拟主机,这种主机是否值得购买,下面我们一起来看看。1、百度云6元体验三个月(活动时间有限抓紧体验)体验地址:https://cloud.baidu.com/campaign/experience/index.html?from=bchPromotion20182、Ucloud 10元云主机体验地址:https:...

简单测评melbicom俄罗斯莫斯科数据中心的VPS,三网CN2回国,电信双程cn2

melbicom从2015年就开始运作了,在国内也是有一定的粉丝群,站长最早是从2017年开始介绍melbicom。上一次测评melbicom是在2018年,由于期间有不少人持续关注这个品牌,而且站长貌似也听说过路由什么的有变动的迹象。为此,今天重新对莫斯科数据中心的VPS进行一次简单测评,数据仅供参考。官方网站: https://melbicom.net比特币、信用卡、PayPal、支付宝、银联...

declare_serial为你推荐
u盘无法读取U盘无法识别是怎么回事支付宝查询余额我的支付宝如何查询余额拂晓雅阁有什么网站是学电脑技术的`?今日热点怎么删除怎样删除实时热点童之磊华硕的四核平板电脑,怎么样?腾讯文章腾讯罗剑楠是何许人也?ios系统ios是什么意思 ios系统是什么虚拟专用网安卓手机的虚拟专用网设置是什么东西?怎么用?如何快速收录如何让百度快速收录gbk编码表如何制作GBK与Unicode的对照表
域名论坛 亚洲大于500m 京东云擎 100m免费空间 创梦 电子邮件服务器 web服务器的架设 jsp空间 服务器维护方案 idc资讯 老左正传 hostloc 域名评估 如何用qq邮箱发邮件 重庆双线服务器托管 t云 免费mysql数据库 无限流量 web服务器是什么 1元域名 更多