[comp.lang.c++] Question about class hierarchy design for scientific data.

drk@athena.mit.edu (David R Kohr) (11/10/90)

I am posting this message for the benefit of someone in my group
at Lincoln who does not have Usenet access.  Please e-mail all replies
directly to him (at rael@ll.mit.edu) rather than posting a followup
to comp.lang.c++ or sending a reply back to me.

(Start of forwarded message.)

-----

I am working on a data transcription package for experimental data with
features which make it well suited to a class heirerarchy in c++.  The output
of the package consists of five different file formats, each composed of
various record types.  Files will usually have one or more 'header' records
with information about the experiment performed, setup parameters for the
recording machine, calibration constants for the experiment, etc.  Each of
the record types has similar form, and will be derived from a common base
class.  The 'generic' or base record form has a syncronization word, the
length of the record, the type of the record, the fields of arbitrary data
items, and a checksum.  The c++ class for the base record for this package
looks something like the following:

static const short Sync=0x0001;         // Why can't this go in BaseRecord ?!?!?
class BaseRecord
{
private:
  short Length;                         // Length of record, including checksum
  short Type;                           // Record type
                                        // <- Specific data goes here in output
  short CheckSum;                       // Checksum of record
public:
  BaseRecord() {Length=Type=CheckSum=0;}
  BaseRecord( short type) {Type=type; Length=CheckSum=0;}
 
  virtual void Put(){ error(); }
};

The data fields are not actually in the base class, but are output to the
storage device in the above order.

A derived experiment header type looks something like:

class ExpHeader: public BaseData
{
private:
  // Experiment name, date, time, number of data measurements, etc.
public:
  ExpHeader();
  void Put();
};

A derived setup header looks like:

class SetupHeader: public BaseData
{
private:
  // Ambient temperature, machine setup, etc.
public:
  SetupHeader();
  void Put();
};


And, finally, a data record for the experiment looks like:

class ComplexData: public BaseData
{
private:
  float         Time;
  float         RangeStart;
  float         Azimuth;
  int           NumberSamples;
  Complex       *Data;
public:
  ComplexData();
  ComplexData(int samples);
  void Put();
};

  I have used the function Put to output the private members of the class
to a stream, nothing fancy.  This seems to be what c++ is good at, encompassing
the similarities among several data types in a base class, and deriving new
classes from this class, using virtual functions to allow class-specific
input/output (for example).  What seems to me to be confusing is how to
declare a file class.  It would have, in one instance, the classes ExpHeader,
SetupHeader, and at least one ComplexData(probably an array of them, dynamicallyallocated).  The problem is that if I declare the elements of the file to be
pointers to BaseData, I can use the property of virtual functions.  However, it
is not clear to me that this is necessary, since I could just as easily declare
the types within the file to be what they are and invoke the member function
Put of each class directly.  I'm not sure I have explained the problem with
sufficient clarity, but this is my first program in the language and I am
somewhat ignorant of the c++ lexicon and mindset, so I offer my apologies
and thanks to anyone who can offer some commentary.

Bill Lear         M.I.T. Lincoln Laboratory      Group 45 ("Radars 'R' Us")
		  email:  rael@ll.mit.edu
                  phone:  (617)981-3278 (work),   (617)721-9857 (home)

------

(End of forwarded message.)

--
David R. Kohr     M.I.T. Lincoln Laboratory      Group 45 ("Radars 'R' Us")
    email:    DRK@ATHENA.MIT.EDU (preferred)  or  KOHR@LL.LL.MIT.EDU
    phone:    (617)981-0775 (work)	      or  (617)527-3908 (home)