|
|
|
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:
| The definition of specific class attributes (if needed); | |
| The definition of constructors/destructors; | |
| The definition of pure virtual functions from XYSeries: domain(), numPoints() and point(); |
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
};
|
Here comes the implementation of XYSeriesFile (typically xyserfil.cpp).
#include <stdio.h> #include <malloc.h> #include "xyserfil.h" |
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 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 should only deallocate the data set array.
XYSeriesFile::~XYSeriesFile (void) {
if (_x) free(_x);
if (_y) free(_y);
}
|