我正在使用 boost 來(反)序列化一些類。除了一個有std::vector<Artefact*>成員的類外,一切都很好(定義見下文)。我有指標向量的問題。
我可以(反)序列化class Artefact完美的單個實體。
我無法序列化具有指向class Artefact.
我嘗試這樣做時的提升錯誤是:
“未注冊的類 - 未注冊或匯出的派生類”
我得到了一些輸出。存檔檔案:
22 serialization::archive 19 1 0
0 1 0
1 1 0
2 0 0 66 0
類定義
#include <boost/serialization/vector.hpp>
#include <boost/serialization/map.hpp>
...
class Tag {
public:
bool tag = false;
};
class Artefact : public Tag {
public:
std::vector<enjyn_Vertex> vertices;
std::vector<unsigned int> indices;
std::vector<enjyn_Texture*> textures;
glm::vec3 position{ 0.0f };
glm::vec3 scale{ 1.0f };
glm::vec3 rotation{ 0.0f, 1.0f, 0.0f };
float rotation_degrees{ 0.0f };
glm::vec4 colour{ 1.0f, 1.0f, 1.0f, 1.0f };
...
std::vector<Artefact> artefacts; // note, no problem serializing std::vector<Artefact> here
...
};
//Mainly static data and function members
class State {
public:
...
static std::map<std::string, bool> state;
...
}
class Event {
public:
...
virtual void OnMouseFocus(); //Lots of virtual data members like this one here
..
}
//Large class with lots of data and function members.
class Enjyn : public Event, public State {
public:
...
std::vector<Artefact*> artefacts; // I believe this is the problem member
...
}
免費的非侵入式(去)序列化函式
我為所有要存檔的類提供了非侵入式免費序列化函式,包括所有基類和非內置資料成員的序列化函式)。
The serialize function below (de)serializes perfectly for single instances of Artefact:
#include <boost/serialization/export.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
...
void serialize(Archive& ar, Artefact& a, const unsigned int version) {
//ar.template register_type<Artefact>(); ; commented as classes exported see below
ar& boost::serialization::base_object<enjyn_Tag>(a);
ar& a.vertices;
ar& a.indices;
ar& a.textures;
ar& a.position;
ar& a.scale;
ar& a.rotation;
ar& a.rotation_degrees;
ar& a.colour;
ar& a.aabb;
ar& a.bsphere;
ar& a.tex_offset_x;
ar& a.tex_offset_y;
ar& a.tex_scale_x;
ar& a.tex_scale_y;
ar& a.name;
ar& a.artefacts; //works fine for vector of non-pointer vector of Artefact.
}
However when I try to archive an object with a std::vector<Artefact*>, I get:
"unregistered class - derived class not registered or exported"
void serialize(Archive& ar, Enjyn& e, const unsigned int version)
{
//ar.template register_type<enjyn>(); commented as classes exported see below:
ar& boost::serialization::base_object<Event>(e); // not sure whether this is necessary, no tracking requried of base classes.
ar& boost::serialization::base_object<State>(e);
ar.template register_type<Artefact>();
...
ar& e.artefacts; //This is a std::vector<Artefact*> which I cant archive
//if i remove this and add include any 'normal' non-pointer
//built in types the serialization appears to work perfectly.
...
}
Serializing Program Functions
I am serializing single instances of Artefact objects perfectly like this:
if (e.primary_artefact) { //primary_artefact is a pointer to an instance of Artefact
try {
std::string filepath = "test_filename";
std::ofstream o(filepath);
{
boost::archive::text_oarchive oa(o);
oa << *e.primary_artefact;
}
}
catch (std::ifstream::failure e) {
std::cerr << "ERROR:IFSTREAM: " << e.what() << std::endl;
}
catch (boost::archive::archive_exception e) {
std::cerr << "ERROR:BOOST SERIALISATION: " << e.what() << std::endl;
}
}
Attempting to serialize class Enjyn using this function creates error if I include Enjyn.artefacts (std::vector<Artefact*>) in the serialize function:
void serialize_enjyn(enjyn& e, std::string& name)
try {
std::string filepath = name;
std::ofstream o(filepath);
{
boost::archive::text_oarchive oa(o);
oa << e;
}
}
catch (std::ifstream::failure e) {
std::cerr << "ERROR:IFSTREAM: " << e.what() << std::endl;
}
catch (boost::archive::archive_exception e) {
std::cerr << "ERROR:BOOST SERIALISATION: " << e.what() << std::endl;
}
}
I went mad and exported GUIDS for all types in my main program file so all relevant types could be tracked within the archive. Not that this is perticularly necessary. Only tracking of '''class Artefact''' is required.
#include <boost/serialization/export.hpp>
BOOST_CLASS_EXPORT_GUID(glm::vec2, "vec2")
BOOST_CLASS_EXPORT_GUID(glm::vec3, "vec3")
BOOST_CLASS_EXPORT_GUID(glm::vec4, "vec4")
BOOST_CLASS_EXPORT_GUID(Artefact, "enjyn_Artefact")
BOOST_CLASS_EXPORT_GUID(Vertex, "enjyn_Vertex")
BOOST_CLASS_EXPORT_GUID(Texture, "enjyn_Texture")
BOOST_CLASS_EXPORT_GUID(Tag, "enjyn_Tag")
BOOST_CLASS_EXPORT_GUID(State, "enjyn_State")
BOOST_CLASS_EXPORT_GUID(Event, "enjyn_event")
BOOST_CLASS_EXPORT_GUID(Enjyn, "enjyn")
int main(int argc, char* argv[]){
Discussion
Note, the Artefact object is used as a base for other classes. I have not registered those classes or written serialization functions for them as Artefact has no virtual functions, I am trying to serialize Artefact directly (though indirectly also via pointers), and the documentation for registration states:
It turns out that the kind of object serialized depends upon whether the base class (base in this case) is polymophic or not. If base is not polymorphic, that is if it has no virtual functions, then an object of the type base will be serialized. Information in any derived classes will be lost. If this is what is desired (it usually isn't) then no other effort is required.
問題似乎出std::vector<Artefact*> artefact在 Enjyn的成員身上。當我從 Enjyn 的序列化函式中洗掉它時,Enjyn 完美地序列化。我顯然錯過了一些基本的東西:
boost 檔案中的指標、std::vector 和派生型別和基類。
請幫忙!
uj5u.com熱心網友回復:
如果你真的花時間把它變成一個正確的、獨立的例子,你可能會發現沒有問題:

你的公主在另一座城堡里。
Imaging The Flaws
I notice a lot of "gratuitous" use of inheritance (e.g. to inherit static data members), but specifically you inherit Enjyn from Event, which is a polymorphic type.
So my best guess is that this contains your actual issue.
Otherwise, you should be able to go from this live sample.
Caveats
Your code presentation shows some ordering that indicates you may be separating code across source files. In that case, don't fall into the trap of registering your types in a file that doesn't include all the relevant archive types BEFORE the export defitions: docs
BOOST_CLASS_EXPORTin the same source module that includes any of the archive class headers will instantiate code required to serialize polymorphic pointers of the indicated type to the all those archive classes. If no archive class headers are included, then no code will be instantiated.
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/325459.html
