Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!pp!gallo!vasey From: vasey@gallo.ACA.MCC.COM (Ron Vasey) Newsgroups: comp.lang.c++ Subject: Re: Shippable C++ Objects (RFC) Message-ID: <403@gallo.ACA.MCC.COM> Date: 28 Nov 89 22:58:59 GMT Reply-To: bryan@kewill.uucp Organization: MCC, Austin, TX Lines: 81 [Posted for Bryan Boreham -- please reply to him.] --- I have been reading the discussion about shipping C++ objects with some interest, and I feel that people would be interested in hearing about the system used in the ET++ class library. In, ET++ almost everything inherits from class Object, and Object declares these methods: virtual ostream& PrintOn (ostream&s); virtual istream& ReadFrom(istream &); The implementation of PrintOn in Object merely prints out the class name; each subclass of Object overrides this to output its instance variables, and call the superclass version. Here is (a contrived) one for a class Shape: ostream &Shape::PrintOn(ostream &s) { Object::PrintOn(s); return s << contentRect << pattern; } Also in Object, there is a virtual method IsA(), which returns a pointer to a meta-class structure that knows things like the name of the class. One such meta-class object is constructed statically at program startup for each subclass of Object; the programmer must write a simple line in her code to invoke this. More complicated objects have more sophisticated PrintOn methods, and their corresponding ReadFrom. For example, class Collection outputs each object it holds in turn. During the outputing of a structure, the meta-class objects build a table of all the objects output so far, and when the same one comes round again, they just output an index number. A sample output of a collection of shapes might be: {Collection #0 4 {Shape #0 (20,40) (80,80) } {Shape #1 (0,40) (20,100) } {Shape #2 (30,0) (0,50) } {Shape #1} } This is slightly simplified over a real ET++ output. Here, the second shape appears twice in the collection, but is only output in full once. In this way, arbitrary cyclic structures are linearised and converted into a form suitable to be transmittted over any channel, or stored in a file. For input, the routine to read in an Object* looks for the '{', then finds the right meta-class; it constructs a blank object, and then calls the virtual ReadFrom method on that blank object. Our Collection will read the number of rows, and then read in each one separately. The braces "{}" serve to make sure that nothing has been dropped, and help humans to read the output. If, when reading in a new object, the system cannot find a meta-class with the right name, it tries to dynamically load that class into the running program. This is (at present) quite simplistic; for class FooBar, it looks for a file FooBar.o. So, there is a table containing a meta-class object for every class in the system; this table (and the program) can be expanded by dynamic linking; the system requires some work on the part of the programmer to set up the meta-class objects and to write the PrintOn/ReadFrom methods, and it all works pretty well. ET++ was written at the University of Zurich; its main function is as a toolkit for Macintosh-like interactive programs; it is in the public domain and you can compile it with cfront 1.2 or g++ 1.36.1, if you are not faint of heart. I hope this is of interest, Bryan Boreham bryan@kewill.uucp Software Engineer || bryan%kewill@uunet.uu.net Kewill Systems PLC || ... uunet!mcvax!ukc!root44!kewill!bryan Walton-On-Thames Surrey, England Telephone: (+44) 932 248 328