MFC Doc/View架构和Boost :: Serialization [英] MFC Doc/View architecture and Boost::Serialization

查看:50
本文介绍了MFC Doc/View架构和Boost :: Serialization的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Stack Overflow上问了这个问题,但没有得到任何答案-我希望你也不要介意我在这里问.

我正在移植现有的MFC C ++应用程序,以对XML文件使用Boost :: Serialization.我的CDocument对象包含该应用程序的所有数据.我已将序列化功能实现为:

I asked this on Stack Overflow but didn''t get any answers - I hope you don''t mind me asking here also.

I''m porting an existing MFC C++ application to use Boost::Serialization for XML files. My CDocument object contains all the data for the app. I''ve implemented the serialize function as:

template<class Archive>
void CMyDoc::serialize(Archive& ar, const unsigned int version)
{
ar  & BOOST_SERIALIZATION_NVP(m_Param1)
    & BOOST_SERIALIZATION_NVP(m_Param2);
}



为了捕获保存和加载事件,在CDoc * .cpp文件中,我重载了基类函数OnOpenDocument()和OnSaveDocument()以实现Boost :: Serialization:



To capture the save and load events, in the CDoc *.cpp file I have overloaded the base class functions OnOpenDocument() and OnSaveDocument() to implement Boost::Serialization:

BOOL CMyDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
clear();    // clear current params

//if (!CDocument::OnOpenDocument(lpszPathName)) // Old MFC serialize code
//  return FALSE;

CEvolveTrafficDoc* pDoc = this; // pointers the same here
std::ifstream ifs(lpszPathName);
boost::archive::xml_iarchive ia(ifs);
ia >> boost::serialization::make_nvp("MyDoc",pDoc); // pointer changes here
// *this = *pDoc; // POSSIBLE solution with CMyDoc copy constructor implemented

return TRUE;
}

BOOL CMyDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
//if (!CDocument::OnSaveDocument(lpszPathName)) // Old MFC serialize code
//  return FALSE;

std::ofstream ofs(lpszPathName);
boost::archive::xml_oarchive oa(ofs);
oa << boost::serialization::make_nvp("MyDoc",this);

return TRUE;
}



保存文档可以正常工作.问题是无法加载文档. Boost库似乎复制了CMyDoc对象,因为指针返回了另一个地址.这意味着已加载的文件未加载到当前文档中. CDoc可以使用boost覆盖自身吗?可以使用MFC CArchive.

我考虑过将行指示为可能的解决方案",但这意味着实现CMyDoc类的副本构造函数.这消除了boost的好处之一,因为我将为每个变量使用两行代码:
1. ar & BOOST_SERIALIZATION_NVP(m_Param1) // for saving and loading to pDoc
2. this->m_Param1 = pDoc.m_Param1 // in CMyDoc copy constructor

如果我超载CMyView来捕获文件打开和保存事件,则Doc/View体系结构提供的MRU列表管理将不会发生.

我敢肯定,这已经做了一百万遍了,但是我无法在网上找到任何信息.奇怪的!任何帮助,不胜感激:D


仔细阅读文档,我发现Boost承认使用新的关键字对任何序列化的指针进行了反序列化:指针的序列化在库中使用类似于以下代码的代码实现:"



Saving a document works fine. The problem is that loading a document doesn''t work. The boost library seems to copy the CMyDoc object because the pointer comes back a different address. This means that the loaded file isn''t loaded into the current document. Can a CDoc overwrite itself with boost? It can with MFC CArchive.

I thought about having the line indicated as "POSSIBLE solution", but this would mean implementing the copy constructor for the CMyDoc class. This removes one of the benefits of boost in that I would have two lines of code for each variable:
1. ar & BOOST_SERIALIZATION_NVP(m_Param1) // for saving and loading to pDoc
2. this->m_Param1 = pDoc.m_Param1 // in CMyDoc copy constructor

If I overload the CMyView to capture the file open and save events, the MRU list management offered by the Doc/View architecture won''t happen.

I''m sure this has been done a million times, but I can''t find any information online. Weird! Any help much appreciated :D


Reading the documentation closer, I see that Boost acknowledges that any serialized pointer is deserialized with a new keyword: "Serialization of pointers is implemented in the library with code similar to the following:"

// load data required for construction and invoke constructor in place
template<class Archive, class T>
inline void load_construct_data(
Archive & ar, T * t, const unsigned int file_version
){
// default just uses the default constructor to initialize
// previously allocated memory. 
::new(t)T();
}



文档建议在必要时重载此功能:



The documentation recommends overloading this function if necessary:

template<class Archive>
inline void load_construct_data(
Archive & ar, my_class * t, const unsigned int file_version
){
// retrieve data from archive required to construct new instance
int attribute;
ar >> attribute;
// invoke inplace constructor to initialize instance of my_class
::new(t)my_class(attribute);
}



但这将再次导致需要实现CMyDoc复制构造函数. Aaarrgghhhh !!



But this would again result in needed to implement a CMyDoc copy constructor. Aaarrgghhhh!!

推荐答案

以防万一,我从罗伯特·拉米(Robert Ramey)那里得到了答复.基本上,我并没有错过任何明显的东西:CMyDoc serialize(Archive& ar,const unsigned int version)函数不是赛跑者,所以我实现了单独的boost_save和boost_load函数.我不得不重载OnOpenDocument和OnSaveDocument,例如:

In case it helps anyone, I had a reply from Robert Ramey about this. Basically, I wasn''t missing something obvious: the CMyDoc serialize(Archive& ar, const unsigned int version) function wasn''t a runner, so I implemented separate boost_save and boost_load functions. I had to overload the OnOpenDocument and OnSaveDocument, for example:

BOOL CMyDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
    clear();
   
    // Call base class function with empty local Serialize function
    // to check file exists etc
    if (!CDocument::OnOpenDocument(lpszPathName))
        return FALSE;

    std::string file( lpszPathName );
    boost_load(file);
    return TRUE;
}



这是必需的,因为MFC CArchive拥有文件,直到MFC Serialize函数退出为止,不允许boost :: serialization访问文件.甚至在Serialize函数中调用ar.Abort()也不起作用,因为CDocument基类假定ar在返回基类Serialize函数时就存在.



This is necessary since the MFC CArchive owns the file until the MFC Serialize function exits, disallowing boost::serialization to access the file. Even calling ar.Abort() in the Serialize functions doesn''t work because the CDocument base class assumes the ar exists on returning to the base class Serialize function.


这篇关于MFC Doc/View架构和Boost :: Serialization的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆