I am trying to serialize using boost and my classes are polymorphic in nature.
when i compile the code , compiler throws exception .
exception thrown at 0x000007FEFD3DB87D in Serialization.exe: Microsoft C++ exception: boost::archive::archive_exception at memory location 0x000000000017AB30.
I have created a MVSC for the problem.
This is the main function.
#include "pch.h"
#include <iostream>
#include<fstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include "Container.h"
#include "SumOpacityChannel.h"
#include "KeyframeFloat.h"
#include <boost/serialization/export.hpp>
BOOST_CLASS_EXPORT_GUID(SumOpacity_Channel, "SumOpacity_Channel")
BOOST_CLASS_EXPORT_GUID(Keyframebase, "Keyframebase")
int main()
{
const char* fileName = "saved.txt";
Container cont;
SumOpacity_Channel opacityChannel;
SumKeyframeFloat key1, key2;
key1.setName("Key1");
key2.setName("key2");
opacityChannel.AddKeyframe(key1);
opacityChannel.AddKeyframe(key2);
cont.AddChannel(&opacityChannel);
{
// Create an output archive
std::ofstream ofs(fileName);
boost::archive::text_oarchive ar(ofs);
ar & cont;
}
Container c_Restored ;
//load data
{
// create an input stream
std::ifstream ifs(fileName);
boost::archive::text_iarchive ar(ifs);
ar & c_Restored ;
}
do
{
std::cout << '\n' << "Press a key to continue...";
} while (std::cin.get() != '\n');
}
I first create SumOpacity_Channel and than add two KeyframeFloat to the channel.
1) SumOpacity_Channel is subclass of SumChannel.
2) KeyframeFloat is subclass of KeyframeBase.
these are the header files for SumChannel and SumOPacity_Channel
#pragma once
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/vector.hpp>
enum class ChannelType
{
NONE,
POSITION,
ROTATION,
SCALING,
OPACITY,
};
class SumChannel
{
private:
ChannelType type;
public:
SumChannel();
SumChannel(ChannelType type);
SumChannel(const SumChannel& channel);
SumChannel& operator=(const SumChannel& channel);
virtual ~SumChannel() { }
virtual SumChannel* Clone() const = 0;
private:
friend class boost::serialization::access;
template<typename Archive >
void save(Archive& ar, const unsigned int version) const {
ar & type ;
}
template<typename Archive>
void load(Archive& ar, const unsigned int version) {
ar & type ;
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
};
//////////////////////////////////////////////////////////////////////////////
#pragma once
#include "KeyframeFloat.h"
#include "SumChannel.h"
#include <string>
#include <iostream>
#include <vector>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/base_object.hpp>
class SumOpacity_Channel : public SumChannel
{
private:
std::vector<SumKeyframeFloat> keyframes;
public:
SumOpacity_Channel();
SumOpacity_Channel(const SumOpacity_Channel &opacityChannel);
~SumOpacity_Channel();
SumOpacity_Channel& operator=(const SumOpacity_Channel &posChannel);
void AddKeyframe(SumKeyframeFloat key);
void DeleteKeyframe(SumKeyframeFloat key, int number);
virtual SumChannel* Clone() const;
public:
typedef SumChannel _Super;
friend class boost::serialization::access;
template<typename Archive>
void save(Archive& ar, const unsigned int version) const {
ar & boost::serialization::base_object<_Super>(*this);
ar & keyframes;
}
template<typename Archive>
void load(Archive& ar, const unsigned int version) {
ar & boost::serialization::base_object<_Super>(*this);
ar & keyframes;
}
};
The cpp file for SumChannel and SumOpacity channel
#include "pch.h"
#include "SumChannel.h"
SumChannel::SumChannel()
{
this->type = ChannelType::NONE;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
SumChannel::SumChannel(ChannelType type)
{
this->type = type;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
SumChannel::SumChannel(const SumChannel& channel)
{
this->type = channel.type;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
SumChannel& SumChannel::operator=(const SumChannel& channel)
{
this->type = channel.type;
return *this;
}
/////////////////////////////////////////////////////////////////////////////////
#include "pch.h"
#include "SumOpacityChannel.h"
#include <boost/serialization/vector.hpp>
SumOpacity_Channel::SumOpacity_Channel() : SumChannel(ChannelType::OPACITY)
{
}
SumOpacity_Channel::~SumOpacity_Channel()
{
}
SumOpacity_Channel::SumOpacity_Channel(const SumOpacity_Channel &opacityChannel) : SumChannel(opacityChannel)
{
this->keyframes.clear();
for (auto KeyFrame : keyframes)
{
this->keyframes.push_back(KeyFrame);
}
}
SumOpacity_Channel& SumOpacity_Channel::operator=(const SumOpacity_Channel &opacityChannel)
{
SumChannel::operator=(opacityChannel);
this->keyframes.clear();
for (auto KeyFrame : keyframes)
{
this->keyframes.push_back(KeyFrame);
}
return *this;
}
void SumOpacity_Channel::AddKeyframe(SumKeyframeFloat key)
{
keyframes.push_back(key);
}
void SumOpacity_Channel::DeleteKeyframe(SumKeyframeFloat key, int number)
{
keyframes.erase(keyframes.begin() + number);
}
SumChannel* SumOpacity_Channel::Clone() const
{
return (SumChannel*) new SumOpacity_Channel(*this);
}
The Header file for Keyframe Base and Keyframe Float.
#pragma once
#include <string>
#include <iostream>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/base_object.hpp>
enum class KeyframeType
{
NONE,
POSITION,
ROTATION,
MATERIAL,
SCALING,
TEXTURE1,
OPACITY,
};
class Keyframebase
{
protected:
std::string stdstrName;
KeyframeType keyframeType;
public:
Keyframebase();
Keyframebase(KeyframeType keyType);
Keyframebase(const Keyframebase &key);
Keyframebase& operator = (const Keyframebase &key);
std::string getName();
void setName(std::string stdstrName);
private:
friend class boost::serialization::access;
template<typename Archive >
void save(Archive& ar, const unsigned int version) const {
ar & stdstrName & keyframeType;
}
template<typename Archive>
void load(Archive& ar, const unsigned int version) {
ar & stdstrName & keyframeType;
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
};
////////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "KeyframeBase.h"
#include <boost/serialization/serialization.hpp>
class SumKeyframeFloat : public Keyframebase
{
private:
float x;
public:
SumKeyframeFloat();
SumKeyframeFloat(float x);
SumKeyframeFloat(const SumKeyframeFloat& key);
// const Sum_Position& operator=(const Container& container);
SumKeyframeFloat& operator=(const SumKeyframeFloat& key);
void setValue(float x);
void getValue(float *x);
private:
typedef Keyframebase _Super;
friend class boost::serialization::access;
template<typename Archive>
void save(Archive& ar, const unsigned int version) const {
ar & boost::serialization::base_object<_Super>(*this);
ar & x;
}
template<typename Archive>
void load(Archive& ar, const unsigned int version) {
ar & boost::serialization::base_object<_Super>(*this);
ar & x;
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
};
The CPP files for KeyframeBase and Keyframe Float
#include "pch.h"
#include "KeyframeBase.h"
Keyframebase::Keyframebase()
{
stdstrName = "Keyframe";
this->keyframeType = KeyframeType::NONE;
}
Keyframebase::Keyframebase(KeyframeType keyType)
{
this->keyframeType = keyType;
stdstrName = "Keyframe";
}
Keyframebase::Keyframebase(const Keyframebase &key)
{
this->stdstrName = key.stdstrName;
this->keyframeType = key.keyframeType;
}
Keyframebase& Keyframebase::operator = (const Keyframebase &key)
{
this->stdstrName = key.stdstrName;
this->keyframeType = key.keyframeType;
return *this;
}
std::string Keyframebase::getName()
{
return this->stdstrName;
}
void Keyframebase::setName(std::string stdstrName)
{
this->stdstrName = stdstrName;
}
///////////////////////////////////////////////////////////////////////////////////////
#include "pch.h"
#include "KeyframeFloat.h"
SumKeyframeFloat::SumKeyframeFloat() : Keyframebase(KeyframeType::OPACITY)
{
this->x = 0.0;
}
SumKeyframeFloat::SumKeyframeFloat(float x)
{
this->x = x;
}
SumKeyframeFloat::SumKeyframeFloat(const SumKeyframeFloat& key) : Keyframebase(key)
{
this->x = key.x;
}
SumKeyframeFloat& SumKeyframeFloat::operator = (const SumKeyframeFloat& key)
{
Keyframebase::operator=(key);
this->x = key.x;
return *this;
}
void SumKeyframeFloat::setValue(float x)
{
this->x = x;
}
void SumKeyframeFloat::getValue(float *x)
{
*x = this->x;
}
/////////////////////////////////////////////////////////////
The header file for Container
#pragma once
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/split_member.hpp>
#include "SumChannel.h"
#include <boost/serialization/vector.hpp>
#include <memory>
class Container
{
private:
std::vector< SumChannel* > Channels;
public:
Container() { };
~Container()
{
if(Channels.size() > 0 )
for (int i = 0; i < Channels.size(); i++)
{
delete Channels[i];
}
}
Container& operator = (const Container& c)
{
if (Channels.size() > 0)
Channels.clear(); // clear any previous channels
for (int i = 0; i < c.Channels.size(); i++)
{
Channels.push_back(c.Channels[i]->Clone());
}
}
Container(const Container& c)
{
if (Channels.size() > 0)
Channels.clear(); // clear any previous channels
for (int i = 0; i < c.Channels.size(); i++)
{
Channels.push_back(c.Channels[i]->Clone());
}
}
void AddChannel(SumChannel* channel)
{
Channels.push_back(channel->Clone());
}
private:
friend class boost::serialization::access;
template <typename Archive>
void save(Archive& ar, const unsigned version) const {
ar & Channels;
}
template <typename Archive>
void load(Archive& ar, const unsigned version) {
ar & Channels;
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
};
Aucun commentaire:
Enregistrer un commentaire