Back Home Up

Building an Application Series

In this example, the class XYSeriesFile is defined to provide a file input data set. To do so, the programmer should extend the abstract XYSeries class. This time, some steps should be performed:

bulletThe definition of specific class attributes (if needed);
bulletThe definition of constructors/destructors;
bulletThe definition of pure virtual functions from XYSeries: domain(), numPoints() and point();

The Include File

Below, there is an example of the include file for XYSeriesFile (xyserfil.h).

#include "xyser.h"
 
class XYSeriesFile : public XYSeries{   

 public:

   XYSeriesFile (const char *filename);
   virtual ~XYSeriesFile (void);

   void domain (double begin, double end);
   void domain (double& begin, double& end);
   unsigned numPoints(void);
   xybool point (unsigned n, double& x, double& y);

 protected:

   double   _begin;      // domain start
   double   _end;        // domain end
   unsigned _first;      // first index inside domain
   double   *_x, *_y;    // coordinates (data set)
   unsigned _np;	 // num of points
   unsigned _np_dominio; // num of points in domain
};     

The Class Implementation

Here comes the implementation of XYSeriesFile (typically xyserfil.cpp).

The Includes

#include <stdio.h>
#include <malloc.h>
#include "xyserfil.h"

The Redefined Methods

void XYSeriesFile::domain (double begin, double end) {
   _begin = begin;
   _end   = end;
   _first = 0;
 
   while ( _first < _np && _x[_first] < _begin ) _first++;
 
   unsigned last = _first; 
   while ( last < _np && _x[last] < _end ) last++;
   _np_dominio = last - _first;
}
 
void XYSeriesFile::domain (double& begin, double& end) {
   begin = _begin;
   end   = _end; 
}
 
unsigned XYSeriesFile::numPoints (void) {
   return _np_dominio;
}
 
xybool XYSeriesFile::point (unsigned n, double& x, double& y) {
   if (_np_dominio == 0) return xyfalse;
   if (n >= _np_dominio) return xyfalse;

   n += _first;

   x = _x[n]; y = _y[n];
   return xytrue;
}


The Constructor Definition

The constructor mounts an array of values. The values are read from the input file (parameter of constructor).

	

XYSeriesFile::XYSeriesFile (const char *filename) {
   FILE *f = fopen (filename, "r");
   if (f == 0) return;

   double x, y;
   unsigned num_alocados = 16;
   _np = 0;
   _x = (double *) malloc (sizeof (double) * num_alocados);

   if (_x == 0) {
      fclose (f);
      return;
   }

   _y = (double *) malloc (sizeof (double) * num_alocados);
   if (_y == 0) {
      free (_x);
      _x = 0;
      fclose (f);
      return;
   }

   while (fscanf (f, "%lf %lf", &x, &y) == 2) {
      if (_np == num_alocados) {
         num_alocados *= 2;
         _x = (double *) realloc (_x,sizeof (double) * num_alocados);
         _y = (double *) realloc (_y,sizeof (double) * num_alocados);
      }

      _x[_np] = x;
      _y[_np] = y;

      ++_np;
   }
   
   --_np;

   _first = 0;
   _begin = _x[0];
   _end   = _x[_np];
   _np_dominio = _np;
   
   fclose (f);
}

The Destructor Definition

The destructor should only deallocate the data set array.

XYSeriesFile::~XYSeriesFile (void) {
   if (_x) free(_x);
   if (_y) free(_y);
}