From: nelsonc@colossus.cs.rpi.edu (Chris Nelson)
Subject: Class design problem
Organization: Rensselaer Polytechnic Institute, Troy, NY
Date: Mon, 23 Nov 1992 22:42:43 GMT


I've built a class hierarchy for dealing with the data files from several
different pieces of laboratory equipment and now I'm running into problems
adding a new feature to the system.  I'm looking for advice.
 
All of the classes have in common a set of evenly spaced Y values for a
range of X values.  In other works, X = 1,2,3,4 or 2,4,6,8 or 6,9,12,15,18
and I have Y=[Y1, Y2, Y3, Y4 ...] corresponding to these X values.  My basic
class definition is (abbreviated):
 
   class SampleDataSet {
      protected:
         double* Data;
         unsigned Samples; // sizeof(Data)/sizeof(double)
         float StartX;
         float EndX;
         float DeltaX; // 1 + (EndX - StartX)/Samples
      public:
         SimpleDataSet();
         ~SimpleDataSet();
         virtual int LoadData(FILE* F);
         virtual int SaveData(FILE* F);
   };
 

I've also got another class which adds some functionality (not related to
the apparatus) to make a DataSet:
 
    class DataSet : public SimpleDataSet, public Other {
    };
 
And then I derive several apparatus-specific classes from DataSet:
 
    +----------+   +----------+
    |  Simple  |   |  Other   |
    +----------+   +----------+
             |       |
            +---------+
            | DataSet |
            +---------+
             |   |   |
   +----------+  |  +----------+
   | SetType1 |  |  | SetType3 |
   +----------+  |  +----------+
                 |
           +----------+
           | SetType2 |
           +----------+
 
Now I've got to add a method to splice two data sets to make a new one.  For
example, if Sa and Sb are SetType1 with Sa having values from X=1 to X=4 and
Sb having values from X=3 to X=10, I need to do something like
 
   Sc = Sa.SpliceIn(Sb)
 
and have Sc be a SetType1 with values from X=1 to X=10.
I tried adding
 
    DataSet* DataSet::Splice(DataSet* P);
 
but Sc ended up being of type DataSet (of course).  This meant that the
wrong LoadData() and SaveData() methods were called for Sc.
 
Then I tried making Splice abstract:
 
    virtual DataSet* DataSet::Splice(DataSet* P) = 0;
 
    virtual SetType1* SetType1::Splice(DataSet* P);
 
but I got a conflict.  (Note that the argument to Splice can be a basic
DataSet because no SetType_-specific behaviour is used in Splice.
 
I think what I need is to "xerox" one of the source data sets and then
splice into it.  Something like:
 
      Sc = Sa.Xerox();
      Sc.SpliceIn(Sb);
 
But I haven't figured out how to write Xerox().  In Borland Pascal
(with Objects), the equivalent of new will take a variable identifier
and figure out it's type so I'd could do something like:
 
      Sc = new Sa;
 
but as far as I can tell, that doesn't work in C++.  I'll take any advice
(other than scrapping my hierarchy) that I can get.  Thanks in advance.
 
                                  Chris       

-- 
------------------------------+------------------------------------------
Chris Nelson                  |  Rens-se-LEER is a county.
Internet: nelsonc@cs.rpi.edu  |  RENS-se-ler is a city. 
CompuServe: 70441,3321        |  R-P-I is a school in Troy!