事件类序列化
Event class serialization
您好,我正在检查C++中的各种对象序列化方法,但找不到合适的解决方案。我现在正在检查的是使用宏来序列化各种类。代码可以编译,但是当函数 serialize_example();
调用Event* newEvent = dynamic_cast<Event*>(Persistent::load(stream));
时,我0xC0000005: Access violation reading location 0xCCCCCCC8.
Persistent * obj = dynamic_cast<Persistent *>(clone);
调用中发生异常。任何人都可以帮我解决这个问题吗?这是代码:
void serialize_example()
{
auto_ptr<Event> event(new Event());
fstream file("try.data",
ios::out | ios::in | ios::binary | ios::trunc);
ArchiveFile stream(&file);
if (!file)
throw "Unable to open file for writing";
event->store(stream);
file.seekg(0, ios::beg);
Event* newEvent = dynamic_cast<Event*>(Persistent::load(stream));
event.reset(newEvent);
file.close();
}
事件.h
#pragma once
#include "Persist.h"
#define PERSISTENT_DECL(className)
public:
virtual Clonable* createObj()
{
return new className();
}
private:
static AddClonable _addClonable;
#define PERSISTENT_IMPL(className)
AddClonable className::_addClonable(#className, new className());
class Event : public Persistent {
private:
int _id;
public:
Event() : _id(0) {}
virtual ~Event() {}
int getId() { return _id; }
protected:
virtual void serialize(Archive& stream)
{
if (stream.isStoring())
stream << _id;
else
stream >> _id;
}
PERSISTENT_DECL(Event)
};
PERSISTENT_IMPL(Event)
坚持.cpp
#include "Persist.h"
#include <vector>
#include <iostream>
using namespace std;
Archive& Archive::operator<<(int val)
{
write(&val, sizeof(int));
return *this;
}
Archive& Archive::operator>>(int& val)
{
read(&val, sizeof(int));
return *this;
}
Archive& Archive::operator<<(const string& str)
{
int length = str.length();
*this << length;
write(str.c_str(), sizeof(char) * length);
return *this;
}
Archive& Archive::operator>>(string& str)
{
int length = -1;
*this >> length;
vector<char> mem(length + 1);
char* pChars = &mem[0];
read(pChars, sizeof(char) * length);
mem[length] = NULL;
str = pChars;
return *this;
}
void ArchiveFile::write(const void* buffer, size_t length)
{
_stream->write((const char*)buffer, length);
if (!*_stream)
throw "ArchiveFile::write Error";
}
void ArchiveFile::read(void* buffer, size_t length)
{
_stream->read((char*)buffer, length);
if (!*_stream)
throw "ArchiveFile::read Error";
}
void Persistent::store(Archive& stream) const
{
string className = typeid(*this).name();
className = className.substr(className.find(' ') + 1);
stream << className;
int ver = version();
stream << ver;
stream.setDirection(true);
const_cast<Persistent *>(this)->serialize(stream);
}
Persistent* Persistent::load(Archive& stream)
{
string className;
stream >> className;
Clonable* clone = Clonables::Instance().create(className.c_str());
if (clone == NULL)
throw "Persistent::load : Error creating object";
auto_ptr<Clonable> delitor(clone);
Persistent * obj = dynamic_cast<Persistent *>(clone);
if (obj == NULL) {
throw "Persistent::load : Error creating object";
}
int ver = -1;
stream >> ver;
if (ver != obj->version())
throw "Persistent::load : unmatched version number";
stream.setDirection(false);
obj->serialize(stream);
delitor.release();
return obj;
}
动态.h
#pragma once
#include <string>
using namespace std;
#include <map>
class Clonable
{
public:
virtual ~Clonable() {}
virtual Clonable* createObj() = 0;
};
class Clonables {
private:
typedef map<string, const Clonable*> NameToClonable;
NameToClonable __clonables;
private:
Clonables() {}
Clonables(const Clonables&); // Prevent copy-construction
Clonables& operator=(const Clonables&); // Prevent assignment
~Clonables()
{
for (NameToClonable::const_iterator it = __clonables.begin(); it != __clonables.end(); it++) {
const Clonable* clone = it->second;
delete clone;
}
__clonables.clear();
}
public:
static Clonables& Instance()
{
static Clonables instance; // Guaranteed to be destroyed.
return instance; // Instantiated on first use.
}
public:
void addClonable(const char* className, const Clonable* clone)
{
string name = className;
NameToClonable::const_iterator it = __clonables.find(name);
if (it == __clonables.end()) {
__clonables[name] = clone;
}
}
Clonable* create(const char *className)
{
string name = className;
NameToClonable::const_iterator it = __clonables.find(name);
if (it == __clonables.end()) return NULL;
const Clonable* clone = it->second;
}
};
class AddClonable {
public:
AddClonable(const char* className, const Clonable* clone) {
Clonables::Instance().addClonable(className, clone);
}
};
您可以使用 Boost.Serialization 作为示例。我想在这里举一个例子。您可以轻松序列化对象重载和运算符。
#include <fstream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
struct plane {
std::string id;
std::string name;
int x;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & id;
ar & name;
ar & x;
}
};
int serialization()
{
{
plane old_plane;
old_plane.id = "12345";
old_plane.id = "plane foo";
old_plane.x = 12345;
// boost::archive::text_oarchive oa(ofs);
std::ofstream ofs("filename");
boost::archive::binary_oarchive oa(ofs);
oa << old_plane;
}
///////////////////////////////////////////////////////////////
plane new_plane;
std::ifstream ifs("filename");
//boost::archive::text_iarchive ia(ifs);
boost::archive::binary_iarchive ia(ifs);
ia >> new_plane;
///////////////////////////////////////////////////////////////
std::cout << new_plane.id << " ";
std::cout << new_plane.name << " ";
std::cout << new_plane.x << std::endl;
return 0;
}
相关文章:
- 如何在C++中序列化结构数据
- 序列化,没有库的整数,得到奇怪的结果
- 如何知道QDataStream不能反序列化某些内容
- 如何使用Python从C++中读取谷物序列化数据
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- 带有Protobuf序列化的C++Hazelcast:字符串不是UTF-8格式的
- 自定义对象的dlib序列化在gcc中失败
- C++boost序列化多态性问题
- 增强基于 XML class_id的反序列化
- 提升反序列化对象具有 nan 或 -nan 值
- 在 cpp 中的平面缓冲区中序列化对象
- 每次进行继承时都需要提升::序列化::base_object吗?
- 如何在 c++ 非托管代码中反序列化 byte[] 的 json 字符串?
- 提升序列化 1:73 的向后兼容性问题
- 将 boost 序列化对象的 asio::streambuf 表示转换为 Beast 的 DynamicBody req.body()
- 为什么 nlohmann/json 序列化 "null" 而不是在 double 上"0"?
- 如何反序列化数组?
- 如何使用提升序列化?
- 序列化多晶型接口
- 事件类序列化