0
你好我正在檢查C++中的各種對象序列化方法,但我找不到合適的解決方案。我正在檢查的一個正在使用宏來序列化各種類。代碼編譯,但我得到0xC0000005: Access violation reading location 0xCCCCCCC8.
當功能serialize_example();
正在呼叫Event* newEvent = dynamic_cast<Event*>(Persistent::load(stream));
事件類序列化
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();
}
Event.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)
Persist.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;
}
Dynamics.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);
}
};
這是太多的代碼分析,並沒有MCVE我們嘗試自己編譯它。因此,沒有回答,只有一個評論:查看Boost序列化。 –
您錯過了'Cloneables.create(...)'中的return語句以及可能更多的代碼。 – aslg