After having a little closer look to boost::serialization I'm also convinced there is no straightforward solution for you request. As you already mentioned the tracking behavior for the serialization is declared on a class by class base with BOOST_CLASS_TRACKING. This const global information is than interpret in the virtual method tracking from class oserializer.
virtual bool tracking(const unsigned int /* flags */)
Because this is a template class you can explicitly instantiate this method for your classes.
namespace boost {
namespace archive {
namespace detail {
template<>
virtual bool oserializer<class binary_oarchive, class AClass >::tracking(const unsigned int f /* flags */) const {
return do_your_own_tracking_decision();
}
}}}
Now you can try to e.g have something like a global variable and change the tracking behavior from time to time. (E.g depending on which derivate class is written to the archive.) This seems to wok for “Serializing“ but the “Deserializing“ than throw an exception. The reason for this is, that the state of “tracking” for each class is only written ones to the archive. Therefore the deserialize does always expect the data for AClass if BClass or CClass is read (at leased if the first write attempt for AClass was with tracking disabled).
One possible solution could be to use the flags parameter in tracking() method. This parameter represent the flags the archive is created with, default “0”.
binary_oarchive(std::ostream & os, unsigned int flags = 0)
The archive flags are declared in basic_archive.hpp
enum archive_flags {
no_header = 1, // suppress archive header info
no_codecvt = 2, // suppress alteration of codecvt facet
no_xml_tag_checking = 4, // suppress checking of xml tags
no_tracking = 8, // suppress ALL tracking
flags_last = 8
};
no_tracking seems currently not to be supported, but you can now add this behavior to tracking.
template<>
virtual bool oserializer<class binary_oarchive, class AClass >::tracking(const unsigned int f /* flags */) const {
return !(f & no_tracking);
}
Now you can at leased decide for different archives whether AClass should be tracked or not.
boost::archive::binary_oarchive oa_nt(ofs, boost::archive::archive_flags::no_tracking);
And this are the changes in your example.
int main() {
cout << "Serializing...." << endl;
{
ofstream ofs("serialization1.dat");
boost::archive::binary_oarchive oa_nt(ofs, boost::archive::archive_flags::no_tracking);
//boost::archive::binary_oarchive oa(ofs);
for(int i=0;i<5;i++)
{
AClass* baseClassPointer = new BClass();
// serialize object through base pointer
oa_nt << baseClassPointer;
// free the pointer so next allocation can reuse memory address
delete baseClassPointer;
}
ofstream ofs2("serialization2.dat");
boost::archive::binary_oarchive oa(ofs2);
//boost::archive::binary_oarchive oa(ofs);
for(int i=0;i<5;i++)
{
AClass* baseClassPointer = new CClass();
// serialize object through base pointer
oa << baseClassPointer;
// free the pointer so next allocation can reuse memory address
delete baseClassPointer;
}
}
getchar();
cout << "Deserializing..." << endl;
{
ifstream ifs("serialization1.dat");
boost::archive::binary_iarchive ia(ifs);
try{
while(true){
AClass* a;
ia >> a;
delete a;
}
}catch(boost::archive::archive_exception const& e)
{
}
ifstream ifs2("serialization2.dat");
boost::archive::binary_iarchive ia2(ifs2);
try{
while(true){
AClass* a;
ia2 >> a;
delete a;
}
}catch(boost::archive::archive_exception const& e)
{
}
}
return 0;
}
namespace boost {
namespace archive {
namespace detail {
template<>
virtual bool oserializer<class binary_oarchive, class AClass >::tracking(const unsigned int f /* flags */) const {
return !(f & no_tracking);
}
}}}
This still may not be what you are looking for. There are lot more methods which could be adapted with an own implementation. Or your have to derivate your own archive class.