problem on saving object relations.

Discussion in 'C++' started by shuisheng, Oct 30, 2006.

  1. shuisheng

    shuisheng Guest

    Dear All,

    Assume I have two classes: material and shape, as follows

    class Material
    {
    double density; // material attribute, may have more
    vector<Shape*> pShape; // shape objects assocaited the material.
    };

    class Shape
    {
    double size; // shape attribute, may have more
    vector<Material*> pMaterial; // material objects associated with the
    shape
    };

    and I have two objects:

    vector<Material*> pMaterial;
    vector<Shape*> pShape;

    And I want to save the two objects into a file and then open it by
    using fstream. But here pointer is used to represent the association
    relation. If I simply save the pointer address in to the file, when
    opening there is no gurantee to have those materials and shapes at the
    same address. Is there any good way to solve the problem?

    Thanks,

    Shuisheng
    shuisheng, Oct 30, 2006
    #1
    1. Advertising

  2. shuisheng

    Adrian Guest

    shuisheng wrote:
    > Dear All,
    >
    > Assume I have two classes: material and shape, as follows
    >
    > class Material
    > {
    > double density; // material attribute, may have more
    > vector<Shape*> pShape; // shape objects assocaited the material.
    > };
    >
    > class Shape
    > {
    > double size; // shape attribute, may have more
    > vector<Material*> pMaterial; // material objects associated with the
    > shape
    > };
    >
    > and I have two objects:
    >
    > vector<Material*> pMaterial;
    > vector<Shape*> pShape;
    >
    > And I want to save the two objects into a file and then open it by
    > using fstream. But here pointer is used to represent the association
    > relation. If I simply save the pointer address in to the file, when
    > opening there is no gurantee to have those materials and shapes at the
    > same address. Is there any good way to solve the problem?


    How about creating an instance_id for each object created. And when you save
    them use this instead of the pointer. If you use a map you can look them up by.

    #include <map>

    class Shape;

    class Material
    {
    static unsigned int next_instance;
    unsigned int instance;
    std::map<int, Shape*> Shape_id;

    Material() : instance(next_instance++) {};
    };

    class Shape
    {
    static unsigned int next_instance;
    unsigned int instance;
    std::map<int, Material*> Material_id;

    Shape() : instance(next_instance++) {};
    };


    Adrian
    Adrian, Oct 30, 2006
    #2
    1. Advertising

  3. shuisheng

    Hooyoo Guest

    I think you can adjust the order of saving to keep this relationship.
    For example, after you saving a material object, you save all shape
    objects whose pMaterial equal the material object's address.
    Adrian 写é“:

    > shuisheng wrote:
    > > Dear All,
    > >
    > > Assume I have two classes: material and shape, as follows
    > >
    > > class Material
    > > {
    > > double density; // material attribute, may have more
    > > vector<Shape*> pShape; // shape objects assocaited the material.
    > > };
    > >
    > > class Shape
    > > {
    > > double size; // shape attribute, may have more
    > > vector<Material*> pMaterial; // material objects associated with the
    > > shape
    > > };
    > >
    > > and I have two objects:
    > >
    > > vector<Material*> pMaterial;
    > > vector<Shape*> pShape;
    > >
    > > And I want to save the two objects into a file and then open it by
    > > using fstream. But here pointer is used to represent the association
    > > relation. If I simply save the pointer address in to the file, when
    > > opening there is no gurantee to have those materials and shapes at the
    > > same address. Is there any good way to solve the problem?

    >
    > How about creating an instance_id for each object created. And when you save
    > them use this instead of the pointer. If you use a map you can look them up by.
    >
    > #include <map>
    >
    > class Shape;
    >
    > class Material
    > {
    > static unsigned int next_instance;
    > unsigned int instance;
    > std::map<int, Shape*> Shape_id;
    >
    > Material() : instance(next_instance++) {};
    > };
    >
    > class Shape
    > {
    > static unsigned int next_instance;
    > unsigned int instance;
    > std::map<int, Material*> Material_id;
    >
    > Shape() : instance(next_instance++) {};
    > };
    >
    >
    > Adrian
    Hooyoo, Oct 31, 2006
    #3
  4. shuisheng wrote:
    > Dear All,
    >
    > Assume I have two classes: material and shape, as follows
    >
    > class Material
    > {
    > double density; // material attribute, may have more
    > vector<Shape*> pShape; // shape objects assocaited the material.
    > };
    >
    > class Shape
    > {
    > double size; // shape attribute, may have more
    > vector<Material*> pMaterial; // material objects associated with the
    > shape
    > };
    >
    > and I have two objects:
    >
    > vector<Material*> pMaterial;
    > vector<Shape*> pShape;
    >
    > And I want to save the two objects into a file and then open it by
    > using fstream. But here pointer is used to represent the association
    > relation. If I simply save the pointer address in to the file, when
    > opening there is no gurantee to have those materials and shapes at the
    > same address. Is there any good way to solve the problem?


    There are several solutions to this. Look up information about object
    streaming.

    The basics is to hold a map of something like:

    std::map< void *, int > pointers;

    As you serialise every time you come across a new pointer you enter it
    in the map something like this:

    pointers[ p ] = pointers.size();

    You then write the number that you have in the map into the file
    instead of the pointer.

    As you load them from disk you do the reverse:

    std::map< int, void * > pointers;

    You will need to use a placement new to construct the objects and
    you'll also need to be able to get the types somehow, some sort of
    factory for the objects you stream. There are a number of these sorts
    of detail that you need to get straight and they can get quite tricky.

    Many years ago (using C++ compilers much worse than those today) I
    wrote a Dr. Dobbs article explaining the approach in a bit more detail.
    I wouldn't implement it anything like that today with a decent compiler
    though, although you should be able to pick up more detail on the
    general approach.
    http://www.ddj.com/184409645?pgno=3


    K
    =?iso-8859-1?q?Kirit_S=E6lensminde?=, Oct 31, 2006
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Nicolas STAMPF
    Replies:
    0
    Views:
    403
    Nicolas STAMPF
    May 4, 2004
  2. John Kandell
    Replies:
    4
    Views:
    4,155
    eeebop
    Dec 10, 2004
  3. loris_p
    Replies:
    0
    Views:
    926
    loris_p
    Jul 6, 2008
  4. Mikaël PLOUHINEC

    Problem display several DataTables with relations

    Mikaël PLOUHINEC, Dec 21, 2006, in forum: ASP .Net Datagrid Control
    Replies:
    0
    Views:
    675
    Mikaël PLOUHINEC
    Dec 21, 2006
  5. Knut Franke
    Replies:
    15
    Views:
    186
    Knut Franke
    Sep 19, 2010
Loading...

Share This Page