【问题标题】:Visual C++, CArchive SerializeVisual C++、CArchive 序列化
【发布时间】:2025-12-14 10:55:02
【问题描述】:

我使用 Visual Studio 2010 学习 Visual C++。 我尝试使用 MFC CObject 的序列化功能。 我无法使用序列化函数加载我的对象 我的代码:

#include <afxwin.h>
#include <iostream>

using std::cout;
using std::endl;

// CMyObject

class CMyObject : public CObject
{
public:
    int x, y;
    CMyObject(int _x=0, int _y=0) : CObject(), x(_x), y(_y) {}
    void Serialize(CArchive &ar);
    void Print() const;
    DECLARE_SERIAL(CMyObject)
};

IMPLEMENT_SERIAL(CMyObject, CObject, 1)

void CMyObject::Serialize(CArchive &ar)
{
    CObject::Serialize(ar);
    if (ar.IsStoring())
        ar << x;
    else
        ar >> x;
}

void CMyObject::Print() const
{
    cout << "CMyObject (" << x << "," << y << ")" << endl;
}



int main()
{
    CMyObject cm(1,3);
    CFile fileS, fileL;
    fileS.Open(L"C:\\CMyObject.dat", CFile::modeWrite | CFile::modeCreate);
    CArchive arStore(&fileS, CArchive::store);

    cm.Print();
    cm.Serialize(arStore);
    arStore.Close();

    cm.x = 2;
    cm.Print();

    fileL.Open(L"C:\\CMyObject.dat", CFile::modeRead);
    CArchive arLoad(&fileL, CArchive::load);
    cm.Serialize(arLoad);
    cm.Print();
    arLoad.Close();
}

程序死在字符串上:

    cm.Serialize(arLoad);

你能告诉我这段代码有什么问题吗?

【问题讨论】:

    标签: c++ serialization mfc carchive


    【解决方案1】:

    您应该检查对Open() 的调用是否失败。完成写入后忘记关闭文件。关闭归档对象后添加fileS.Close();

    if(!fileS.Open(L"C:\\source\\CMyObject.dat", CFile::modeWrite | CFile::modeCreate))
    {
        std::cout << "Unable to open output file" << std::endl;
        return 1;
    }
    CArchive arStore(&fileS, CArchive::store);
    cm.Print();
    cm.Serialize(arStore);
    arStore.Close();
    fileS.Close();  //  <--- close the file
    
    
    if(!fileL.Open(L"C:\\source\\CMyObject.dat", CFile::modeRead))
    {
        std::cout << "Unable to open input file" << std::endl;
        return 1;
    }
    CArchive arLoad(&fileL, CArchive::load);
    cm.Serialize(arLoad);
    cm.Print();
    arLoad.Close();
    fileL.Close();  //  <--- close the file
    

    【讨论】:

    • 谢谢,这是一个决定。我感谢 arStore.Close() 也会关闭 fileS。
    【解决方案2】:

    为了让 MFC 在反序列化期间动态创建对象,您的类定义必须提供不带参数的构造函数。参考:

    http://msdn.microsoft.com/en-us/library/47ecfxkh.aspx

    【讨论】:

    • CMyObject(int _x=0, int _y=0) : CObject(), x(_x), y(_y) {}
    • 来自标准 - 12.2/5 - 类 X 的默认构造函数是类 X 的构造函数,可以在没有参数的情况下调用。