Closed Astrarog closed 4 years ago
User-defined serializable types must be default constructible. Otherwise, behavior-only public inheritance like this should work as expected. The encoder templates should instantiate for Derived the same way they do for Base.
Are you getting an error when you pass instances of Derived to the serializer?
Thank you for the response!
The structure above works perfectly without any errors. I suppose it was my misunderstanding of how NOP_STRUCTURE
macro works. As I understand, if the Derived
is inheritant form the Base
class with NOP_STRUCTURE
provided then Derived class can be serialized as well.
I've done some research and found out that in the example below Derived
class serizalizes not only the foo
and bar
fields from Base
class but also its own a
and b
fields
struct Base
{
int foo;
int bar;
NOP_STRUCTURE(Base, foo, bar);
};
struct Derived : public Base
{
int a;
int b;
};
Moreover it is esaly possible to serialize and deserialize one into another:
using Writer = nop::StreamWriter<std::stringstream>;
using Reader = nop::StreamReader<std::stringstream>;
Derived derivedObject;
Base baseObject;
nop::Serializer<Writer> serializer;
serializer.Write(someObject);
nop::Deserializer<Reader> deserializer{serializer.writer().take()};
deserializer.Read(&otherObject);
// baseObject will take the data from derivedObject
I think this all of this is worth mentioning in Getting startred page
Hi Astrarog,
I may be misunderstanding your statements, but I think your comment about the fields in Derived
being serialized is incorrect. In the example you provided the serializer/deserializer will not touch a
or b
at all. Instead, the serializer/deserializer treats both Base
and Derived
as equivalent because they have the same field description provided by NOP_STRUCTURE
.
The way NOP_STRUCTURE(Type, Fields...)
works is by constructing a description of the fields using the type system to capture the pointer-to-member of each field. This description is stored in the type alias NOP__MEMBERS
within the scope of the struct/class: https://github.com/google/libnop/blob/master/include/nop/structure.h#L62
When Base
is passed to the serializer, the encoder templates see that Base::NOP__MEMBERS
is defined and use it to build an encoder for the number, type, and order of the fields. When Derived
is passed to the deserializer it sees the field description inherited from Base
(i.e. Base::NOP_MEMBERS
and Derived::NOP_MEMBERS
are the same) and builds a decoder for the same set of fields. It does not, however, know anything about Derived::a
or Derived::b
and leaves them alone entirely.
So you are right that you can interchange Base
and Derived
when serializing/deserializing. However, the additional fields introduced in Derived
don't participate at all.
I hope this clears things up!
Hello!
You are right. It was just my wrong obersvation while using libnop.
But I have a question then. So, what should I do to have the ability serialize/deserialize Derived
with Derived::a
and Derived::b
? Is it enough to add NOP_STRUCTURE(Derived, a, b)
inside the Derived
definition or this macro will override the Derived::NOP_MEMBERS
that was inherited from the Base::NOP_MEMBERS
? In this case, what should be done to append NOP_MEMBERS
to existing Derived::NOP_MEMBERS
?
The library isn't designed to support data modeling using inheritance. You could make the members of Base
protected and then include them in the member list in Derived
: NOP_STRUCTURE(Derived, a, b, foo, bar)
. However, if you do this you won't be able to use Base
and Derived
interchangeably when serializing/deserializing.
Instead, you can use composition to build up more complex types. For example:
struct Point3d {
float x;
float y;
float z;
NOP_STRUCTURE(Point3d, x, y, z);
};
struct Triangle3d {
Point3d vertices[3];
NOP_STRUCTURE(Triangle3d, vertices);
};
Hello! Have you support user-defined structures with inheritance? I have the following data structures where only Base class stores data and Derived classes are only interfaces around the Base class.
So, how can I serialize an instance of Derived class?