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);
}
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();
CEvolveTrafficDoc* pDoc = this;
std::ifstream ifs(lpszPathName);
boost::archive::xml_iarchive ia(ifs);
ia >> boost::serialization::make_nvp("MyDoc",pDoc);
return TRUE;
}
BOOL CMyDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
std::ofstream ofs(lpszPathName);
boost::archive::xml_oarchive oa(ofs);
oa << boost::serialization::make_nvp("MyDoc",this);
return TRUE;
}
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
EDIT:
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:"
template<class Archive, class T>
inline void load_construct_data(
Archive & ar, T * t, const unsigned int file_version
){
::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
){
int attribute;
ar >> attribute;
::new(t)my_class(attribute);
}
But this would again result in needed to implement a CMyDoc copy constructor. Aaarrgghhhh!!