现在的位置: 首页 > 综合 > 正文

MFC/VC++ 怎样将C++对象存储到数据库并读取出来

2014年03月04日 ⁄ 综合 ⁄ 共 6176字 ⁄ 字号 评论关闭

http://www.vckbase.com/index.php/wv/1190.html

http://blog.csdn.net/wirror800/article/details/4003995

4 使用C++将对象进行序列化的几种方法

使用C++进行对象序列化的方法可以有以下三种:基于Boost库的方法;基于.Net Framework的方法;以及基于MFC的方法。本章将就三种方法的实现机制、实现步骤,以及注意事项进行说明。

由于我们的开发环境在Windows下,部署环境在Unix下,因此我们的开发需要使用两个平台都可以兼容的技术。经过验证,基于.Net和基于MFC的方法仅适用于Windows的环境,而Boost库在Windows和Unix下都有相应的版本,因此在项目中应优先考虑使用Boost库进行对象的序列化。尽管如此,本文中仍然列出使用.Net和MFC进行序列化的方法,以供参考。三种方法相应的代码实现的例子将附在文章之后。

MFC中的序列化:

实现步骤

实现序列化的的类需要满足一系列条件:

1. 该类需要从CObject类派生(可以是间接派生);

2. 在类中中进行DECLARE_SERIAL宏定义;

3. 类存在有缺省的构造函数;

4. 类中实现了Serialize(CArchive&)函数,并且在其中调用基类的序列化函数;

5. 使用IMPLEMENT_SERIAL宏指明类名及版本号。

满足了这些条件之后,就可以进行序列化与反序列化了。

序列化时,首先,实例化一个CArchive类的对象,将其与输出文件相关联;其次,利用CArchive类的<<运算符重载将需要序列化的对象保存在文件中。

反序列化时,将CArchive类的对象与保存对象的文件相关联;然后新建一个需要反序列化的对象,利用CArchive类的>>运算符重载将文件里的内容恢复到需要反序列化的对象中。

 注意事项

使用这种方法需要注意的是:

l  需要包含afx.h头文件;

l  它不支持string类型的序列化,但是支持CString类型的序列化;

l  需要将项目属性中的MFC属性配置为“在共享DLL中使用MFC”或“在静态库中使用MFC”,否则编译时会报错。

举例:

一、新建一个继承于 CObject 的子类 CLine;

头文件:Line.h

01.classCLine :
public
CObject
02.{
03.private:
04.LOGPEN m_logPen;//画笔
05.COLORREFm_crBackColor;
06.CArray<CPoint, CPoint &> m_PointArray;//标记类对应框
07. 
08.public:
09.intGetSize();
10.CPoint GetPoint(intpos);
11.voidDrawLine(CDC *pDC,CPoint pt1,CPoint pt2,CRect
rc);
12.voidDrawBackGround(CDC *pDC,CRect rect);
13.voidDrawPoint(CDC *pDC, CRect rect);
14.voidSetWidth(int
iWidth);
15.COLORREFGetColor();
16.voidSetColor(COLORREF
color);
17. 
18.COLORREFGetBkColor();
19.voidSetBkColor(COLORREF
color);
20. 
21.voidAddPoint(CPoint point);
22.voidClear();
23.CLine();
24.virtual~CLine();
25.virtualvoid
Serialize(CArchive &ar);
26.CLine& operator=(CLine &src);
27.DECLARE_SERIAL(CLine);
28.};

实现文件:Line.cpp

001.//////////////////////////////////////////////////////////////////////
002.// Line.cpp: implementation of the CLine class.
003.//
004.//////////////////////////////////////////////////////////////////////
005. 
006.#include "stdafx.h"
007.#include "TestAdo.h"
008.#include "Line.h"
009. 
010.#ifdef _DEBUG
011.#undef THIS_FILE
012.staticchar
THIS_FILE[]=__FILE__;
013.#define new DEBUG_NEW
014.#endif
015. 
016.IMPLEMENT_SERIAL(CLine,CObject,1)
017. 
018.CLine::CLine()
019.{
020.Clear();
021.}
022.CLine::~CLine()
023.{
024. 
025.}
026.//重写 =
027.CLine& CLine::operator=(CLine &src)
028.{
029.if(this!=&src)
030.{
031.m_logPen = src.m_logPen;
032.m_crBackColor = src.m_crBackColor;
033.}
034.return*this;?
035.}
036.//串行化操作
037.voidCLine::Serialize(CArchive &ar)
038.{
039.if(ar.IsStoring())
040.{
041.ar <<DWORD(m_crBackColor);
042.ar.Write(&m_logPen,sizeof(LOGPEN));
043.}
044.else
045.{
046.DWORDdw;
047.ar >> dw; m_crBackColor =COLORREF(dw);
048.ar.Read(&m_logPen,sizeof(LOGPEN));
049.}
050.m_PointArray.Serialize(ar);
051.}
052. 
053.voidCLine::Clear()
054.{
055.m_crBackColor = RGB(255,255,255);
056.m_logPen.lopnStyle = PS_SOLID;
057.m_logPen.lopnWidth.x = 1;
058.m_logPen.lopnWidth.y = 1;
059.m_logPen.lopnColor = RGB(0, 0, 0);
060.m_PointArray.RemoveAll();
061.}
062.voidCLine::AddPoint(CPoint point)
063.{
064.m_PointArray.Add(point);
065.}
066. 
067.voidCLine::SetColor(COLORREFcolor)
068.{
069.m_logPen.lopnColor = color;
070.}
071.COLORREFCLine::GetColor()
072.{
073.returnm_logPen.lopnColor;
074.}
075.voidCLine::SetBkColor(COLORREFcolor)
076.{
077.m_crBackColor = color;
078.}
079.COLORREFCLine::GetBkColor()
080.{
081.returnm_crBackColor;
082.}
083.voidCLine::SetWidth(int
iWidth)
084.{
085.m_logPen.lopnWidth.x = iWidth;
086.m_logPen.lopnWidth.y = iWidth;
087. 
088.}
089.//绘线条
090.voidCLine::DrawPoint(CDC *pDC, CRect rect)
091.{
092.intlen = m_PointArray.GetSize();
093.if(len <=0)
return;
094.CPen pen;
095.pen.CreatePenIndirect(&m_logPen);
096.CPen *pOldPen = pDC->SelectObject(&pen);
097.CPoint pt = m_PointArray.GetAt(0);
098.pDC->MoveTo(pt);
099.for(int
i=1; i< len; i++)
100.{
101.pt = m_PointArray.GetAt(i);
102.pDC->LineTo(pt);
103.}
104.pDC->SelectObject(pOldPen);
105.pOldPen = NULL;
106.pen.DeleteObject();
107.}
108. 
109.voidCLine::DrawBackGround(CDC *pDC, CRect rect)
110.{
111.CBrush brushCtl;
112.brushCtl.CreateSolidBrush(GetBkColor());
113.pDC->Rectangle(rect);
114.pDC->FillRect(rect,&brushCtl) ;
115.brushCtl.DeleteObject();
116.}
117.voidCLine::DrawLine(CDC *pDC,CPoint pt1, CPoint
pt2, CRect rc)
118.{
119.CPen pen;
120.pen.CreatePenIndirect(&m_logPen);
121.CPen *pOldPen = pDC->SelectObject(&pen);
122.pDC->MoveTo(pt1);
123.pDC->LineTo(pt2);
124.pDC->SelectObject(pOldPen);
125.pOldPen = NULL;
126.pen.DeleteObject();
127.}
128.CPoint CLine::GetPoint(intpos)
129.{
130.if(pos>=0 && pos<m_PointArray.GetSize())?
131.{
132.returnm_PointArray.GetAt(pos);
133.}
134.returnCPoint(0,0);
135.}
136.intCLine::GetSize()
137.{
138.returnm_PointArray.GetSize();
139.}

二、用Ado接口打开数据库

01.BOOLCTestAdoDlg::OpenDb(CString filename)
02.{
03.HRESULThr=S_OK;
04.hr=m_pCon.CreateInstance("ADODB.Connection");
05.if(hr!=S_OK)
06.{
07.returnFALSE;
08.}
09.try
10.{
11._bstr_t sCon;
12.sCon=_bstr_t(filename);//路径名
13.sCon="Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+sCon;
14.hr=m_pCon->Open(sCon,"","",adModeUnknown);
15.if(hr!=S_OK)
16.{
17.returnFALSE;
18.}
19.///////////////////////
20.hr=m_pSet.CreateInstance("ADODB.Recordset");
21.if(hr!=S_OK)
22.{
23.returnFALSE;
24.}
25.m_pSet->CursorLocation=adUseClient;
26.hr=m_pSet->Open("SELECT * FROM object_table",_variant_t((IDispatch*)m_pCon,TRUE),
27.adOpenStatic,adLockOptimistic,adCmdText);
28.if(hr!=S_OK)
29.{
30.returnFALSE;
31.}
32.returnTRUE;
33.///////////////////////
34.}
35.catch(_com_error &e)
36.{
37.CString errorMessage;
38.errorMessage.Format("连接数据库失败!错误信息:%s",e.ErrorMessage());
39.returnFALSE;
40.}
41.returnFALSE;
42.}

(注意:在StdAfx.h中要加入:

1.#import "C:\Program Files\Common Files\SYSTEM\ADO\msado15.dll" no_namespace
rename("EOF","adoEOF")

来引入ado库,还有在 BOOL CTestAdoApp::InitInstance() 加入 AfxOleInit();///初始化COM库)

三、CLine对象的保存

01.voidCTestAdoDlg::OnButtonSave()
02.{
03.//m_List
04.if(!m_bState)
return;
05.UpdateData();
06.try
07.{
08.m_pSet->AddNew();
09.m_pSet->PutCollect("name",
_variant_t(m_sName));
10. 
11.//保存图形对象
12.CMemFile memFile;
13.CArchive ar(&memFile, CArchive::store);
14.m_Line.Serialize(ar);
15.ar.Close();
16. 
17.DWORDdwSize = memFile.GetLength();
18.LPBYTElpInfo = memFile.Detach();
19. 
20.VARIANT varBLOB;
21.SAFEARRAY *psa;
22.SAFEARRAYBOUND rgsabound[1];
23. 
24.rgsabound[0].lLbound = 0;
25.rgsabound[0].cElements = dwSize;
26. 
27.psa = SafeArrayCreate(VT_UI1, 1, rgsabound);
28.for(long
i = 0; i < (long)dwSize; i++)
29.{
30.SafeArrayPutElement (psa, &i, lpInfo++);
31.}
32.varBLOB.vt = VT_ARRAY | VT_UI1;
33.varBLOB.parray = psa;
34.m_pSet->GetFields()->GetItem("object")->AppendChunk(varBLOB);
35.m_pSet->Update();
36.

抱歉!评论已关闭.