Git Product home page Git Product logo

Comments (5)

eieio avatar eieio commented on May 5, 2024 1

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);
};

from libnop.

eieio avatar eieio commented on May 5, 2024

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?

from libnop.

Astrarog avatar Astrarog commented on May 5, 2024

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

from libnop.

eieio avatar eieio commented on May 5, 2024

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!

from libnop.

Astrarog avatar Astrarog commented on May 5, 2024

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?

from libnop.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.