Greg Ercolano wrote:
> belahcene wrote:
>> Hi,
>> I use fltk (C++ graphical interface) to create an electronics design 
>> package. I created a list of objects and placed them on a window. My problem 
>> is how to save the file, I think to create a list in memory for the objects 
>> placed on the sheet and store them in a file.
>> I think (not sure of course) that xfig for example uses this procedure ?
> 
>       Sure sounds like a simple matter of making your class(s) that
>       handle the components have Save() and Load() methods.
> 

Try not to do this.  Greg's code works fine, but it has a number of
maintainance headaches you'll avoid by using some pre-built library like
boost.

The issues with writing your own parser are that:
        a) You have two functions: Save and Load, which you need
           to keep in sync.  Good serialization C++ libraries only use a
           single function for doing both the loading and saving, and
           only split them if needed.

        b) The format you write the file in is known only to you and
           those that read your source code (as you'll usually won't
           bother to write a spec).  This makes the format difficult to
           maintain as it grows, and makes it very hard to make it
           readable in other languages.

        c) Parameters are not named.  As you add new elements in your
           class, it becomes very easy to load the wrong parameter in
           in the wrong location.  sscanf() and printf() routines are
           THE worst routines in that they do no type checking.
           Libraries that use XML or YAML force you to name your
           elements.  If they are written in C++, they'll use C++
           type checking to avoid, for example, assigning a float to
           an int (or worse, to a pointer).

         d) If your class uses inheritance, Greg's format will
            not work properly, without adding additional code and
            possibly changing the format.

         e) If you need to maintain different versions of the file
           format, you may be forced to make the parser more complex.

         f) If you need to save out pointers, no simple printf() works.

         g) If you need to support internationalization, you may also be
            in trouble.


In comparison, this is how your class works with boost serialization:

// --- MyClass.h
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/version.hpp>

class MyClass {
    int degrees, minutes, seconds;

    // Needed
    friend class boost::serialization::access;

    // The actual routine that saves and loads, this does not
    // need to be part of the class and can be done standalone.
    template<class Archive>
    void serialize(Archive & ar, const unsigned int file_version ) {
        ar  & BOOST_SERIALIZATION_NVP(degrees)
            & BOOST_SERIALIZATION_NVP(minutes)
            & BOOST_SERIALIZATION_NVP(seconds);
    }
public:
    MyClass() {}
    MyClass( int d, int m, int s ) :
       degrees(d), minutes(m), seconds(s)   {}

    // ... all other MyClass functions here...
  friend std::ostream& operator<<( std::ostream& o,
                                   const MyClass& b )
  {
    return o << "d: " << b.degrees << " m: " << b.minutes
             << " s:" << b.seconds;
  }
};

///--- write_xml.cpp
/// Example of use to write as xml
/// To compile (unix):
///     g++ -o write_xml write_xml.cpp -lboost_serialization

#include <fstream>
#include <boost/archive/xml_oarchive.hpp>

#include "MyClass.h" // must come after boost/archive

int main()
{
    std::ofstream ofs("demo.xml");
    boost::archive::xml_oarchive oa(ofs);

    MyClass s( 5, 10, 20 );
    oa << BOOST_SERIALIZATION_NVP(s);

   return 0;
}

///--- read_xml.cpp
/// Example of use to read as xml
/// To compile (unix):
///     g++ -o read_xml read_xml.cpp -lboost_serialization

#include <fstream>
#include <iostream> // for std::cout
#include <boost/archive/xml_iarchive.hpp>

#include "MyClass.h" // must come after boost/archive

int main()
{
    std::ifstream ifs("demo.xml");
    boost::archive::xml_iarchive ia(ifs);

    MyClass s;
    ia >> BOOST_SERIALIZATION_NVP(s);

    // Verify
    std::cout << s << std::endl:

   return 0;
}


And that's it.  Not only is the code simpler, but it avoids all other
pitfalls (read the manual for more complex stuff like how to handle
pointers, STL, versioning, etc).


-- 
Gonzalo Garramuño
[EMAIL PROTECTED]

AMD4400 - ASUS48N-E
GeForce7300GT
Kubuntu Edgy

_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to