CArchive使用(2)

mfc初学,本人小白。

继续昨天的工作把我的类进行了改进,发现了不少的错误。

class CCardManage:public CObject
{
	
public:
	CCardManage(void);
	~CCardManage(void);
	int addOne();
	CCardInfo* create();
	int deleteOne(int i);
	int queryInfo( CCardInfo &ci,int queryType);
	int inserOne(CCardInfo* pCI, int iIndex);
	virtual void Serialize(CArchive& ar);
	
	std::vector<CCardInfo> m_vciRecord;
	int m_Index;
	CFile m_file;
private:
	DECLARE_SERIAL(CCardManage)
};


 

红颜色是修改的几个部分,这是穿行化的必要步骤。

以下是实现部分的修改

IMPLEMENT_SERIAL(CCardManage,CObject,1)
void CCardManage::Serialize(CArchive& ar)
{
	
	if (ar.IsStoring())
	{	// storing code
		
		for (std::vector<CCardInfo>::iterator p = m_vciRecord.begin();p != m_vciRecord.end();p++)
		{
			ar <<p->m_cardName<<p->m_cardId<<p->m_cardCar<<p->m_cardDate<<p->m_cardAvailable;
		}
	}
	else
	{	
		
		try{
			while (1)
			{
			
				CCardInfo* pCI1;
				pCI1 = new CCardInfo();
			
				ar>>pCI1->m_cardName>>pCI1->m_cardId>>pCI1->m_cardCar>>pCI1->m_cardDate>>pCI1->m_cardAvailable;
					
				m_vciRecord.push_back(*pCI1);
			
			}
		}
		catch(CArchiveException* e)
		{
			if (e->m_cause != CArchiveException::endOfFile)
			{
				AfxMessageBox(_T("发生未知错误"));
			}
			
		}
		
	}
}


 

出现问题

1.ar>>(对象)必须是指针,这个应该注意。

2.考虑到CArchive是与CFile关联在一起的,那么在CArchive中操作也会影响到CFile中。这个结论部分正确,当在CArchive对象中进行读取操作的时候,CFile中的指针也会移动,但是这个移动不是一一映射的,例如:在CArchive中读30字节,CFile中的指针可能移到4k字节了。(猜测可能是CArchive自己从文件中读满自己的缓冲区,这样就不用频繁的和CFile交互,提高效率)。

思考

对于CArchive读取有三个想法:first,用文件指针指示是否到文间的结尾,即getPosition() != getLength()。second,使用异常来处理。thrid,在文件头中先写入一共有多少个对象,就能知道有多少个记录了。

讨论

由于问题2中,我们可以知道方法一是不可取的,因为文件指针会率先走到文件结尾出,这样会使得CArchive提前停止,记录读不全。

上面的代码使用方法2来实现的,成功。

方法3,处理起来比较麻烦,不过也成功。

 

CArchiveMFC(Microsoft Foundation Classes)中的一个类,用于在C++中进行序列化和反序列化操作。它提供了一种方便的方式来将对象的数据保存到文件或者从文件中读取数据。 使用CArchive进行序列化和反序列化的步骤如下: 1. 创建一个CArchive对象,并指定要进行操作的文件和打开模式(读或写)。 2. 使用CArchive对象的成员函数来读取或写入数据。可以使用<<和>>操作符来序列化和反序列化基本数据类型,也可以使用WriteObject和ReadObject函数来序列化和反序列化自定义的对象。 3. 关闭CArchive对象。 下面是一个简单的示例代码,演示了如何使用CArchive进行序列化和反序列化: ```cpp #include <afx.h> // 包含MFC头文件 class MyData { public: int value1; float value2; CString value3; // 序列化函数 void Serialize(CArchive& ar) { if (ar.IsStoring()) { ar << value1 << value2 << value3; } else { ar >> value1 >> value2 >> value3; } } }; int main() { // 创建一个CArchive对象,并指定要进行操作的文件和打开模式 CFile file(_T("data.dat"), CFile::modeCreate | CFile::modeReadWrite); CArchive ar(&file, CArchive::store); // 创建一个自定义对象 MyData data; data.value1 = 10; data.value2 = 3.14f; data.value3 = _T("Hello, CArchive!"); // 序列化对象到文件 data.Serialize(ar); // 关闭CArchive对象 ar.Close(); file.Close(); // 重新打开文件进行反序列化 file.Open(_T("data.dat"), CFile::modeRead); ar.SetFile(&file, CArchive::load); // 反序列化对象 MyData newData; newData.Serialize(ar); // 关闭CArchive对象 ar.Close(); file.Close(); // 输出反序列化后的数据 printf("value1: %d\n", newData.value1); printf("value2: %f\n", newData.value2); printf("value3: %s\n", newData.value3); return 0; } ``` 以上代码中,首先创建了一个CArchive对象ar,并指定了要进行操作的文件和打开模式。然后,创建了一个自定义的对象data,并调用其Serialize函数将数据序列化到CArchive对象中。接着,关闭CArchive对象和文件。然后,重新打开文件进行反序列化,创建一个新的对象newData,并调用其Serialize函数从CArchive对象中反序列化数据。最后,关闭CArchive对象和文件,并输出反序列化后的数据。 需要注意的是,CArchive类是MFC中的一个类,因此在使用CArchive之前,需要先包含MFC的头文件。另外,CArchive类的使用需要在MFC环境中进行,不能在纯C++环境中使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值