I've attached a shell script that reproduces the problem.
#!/bin/sh
##
## Create BaseClass.hpp
##
cat >BaseClass.hpp <<END_BaseClass.hpp
#ifndef BASE_CLASS_HPP
#define BASE_CLASS_HPP
#include <stddef.h>
#include <math.h>
class BaseClass
{
public:
enum AveragingMethod
{
NONE,
LINEAR,
RMS,
HMS,
MINIMUM,
MAXIMUM,
HARMONIC,
GEOMETRIC,
SUM,
SUM_SQUARED,
STANDARD_DEVIATION,
MAX_OVER_MIN,
MAX_MINUS_MIN,
};
BaseClass( AveragingMethod method ) : avgMethod(method) {}
virtual double get_value( ) = 0;
void set_averaging_method( AveragingMethod method ) { avgMethod = method; }
AveragingMethod get_averaging_method() const { return avgMethod; }
protected:
inline double average_values( double list[], size_t len );
private:
AveragingMethod avgMethod;
};
inline double BaseClass::average_values( double list[], size_t len )
{
size_t i;
double result = 0, other = 0;
switch (avgMethod) {
default:
break;
case LINEAR:
for (i = 0; i < len; ++i)
result += list[i];
result /= len;
break;
case RMS:
for (i = 0; i < len; ++i)
result += list[i] * list[i];
result = sqrt(result/len);
break;
case HMS:
for (i = 0; i < len; ++i)
result += 1.0 / (list[i] * list[i]);
result = sqrt( len / result );
break;
case MINIMUM:
result = HUGE_VAL;
for ( i = 0; i < len; ++i)
if (list[i] < result)
result = list[i];
break;
case MAXIMUM:
result = -HUGE_VAL;
for ( i = 0; i < len; ++i)
if (list[i] > result)
result = list[i];
break;
case HARMONIC:
for (i = 0; i < len; ++i)
result += 1.0 / list[i];
result = len / result;
break;
case GEOMETRIC:
result = 1;
for (i = 0; i < len; ++i)
result *= list[i];
result = pow( result, 1.0/len );
break;
case SUM:
for (i = 0; i < len; ++i)
result += list[i];
break;
case SUM_SQUARED:
for (i = 0; i < len; ++i)
result += list[i] * list[i];
break;
case STANDARD_DEVIATION:
for (i = 0; i < len; ++i) {
result += (list[i] * list[i]);
other += list[i];
}
result = ((other * other) / (len * len)) - result / len;
break;
case MAX_OVER_MIN:
case MAX_MINUS_MIN:
result = -HUGE_VAL;
other = HUGE_VAL;
for (i = 0; i < len; ++i) {
if (list[i] > result)
result = list[i];
if (list[i] < other)
other = list[i];
}
if (avgMethod == MAX_OVER_MIN)
result /= other;
else
result -= other;
break;
}
return result;
}
#endif
END_BaseClass.hpp
##
## Create FileReader.hpp
##
cat >FileReader.hpp <<END_FileReader.hpp
#ifndef FILE_READER_HPP
#define FILE_READER_HPP
#include "BaseClass.hpp"
#include <string>
class FileReader : public BaseClass
{
public:
FileReader( std::string filename ) : BaseClass( LINEAR ),
fileName(filename) {}
virtual double get_value( );
private:
std::string fileName;
};
#endif
END_FileReader.hpp
##
## Create FileReader.cpp
##
cat >FileReader.cpp <<END_FileReader.cpp
#include "FileReader.hpp"
#include <stdio.h>
#include <vector>
double FileReader::get_value()
{
std::vector<double> list;
double d;
FILE* file = fopen( fileName.c_str(), "r" );
if (!file)
return 0;
while (fscanf( file, "%lf", &d ) == 1)
list.push_back(d);
return average_values( &list[0], list.size() );
}
END_FileReader.cpp
##
## Create Random.hpp
##
cat >Random.hpp <<END_Random.hpp
#ifndef RANDOM_HPP
#define RANDOM_HPP
#include "BaseClass.hpp"
class Random : public BaseClass
{
public:
Random( unsigned count ) : BaseClass( RMS ), numValues(count) {}
virtual double get_value( );
private:
unsigned numValues;
};
#endif
END_Random.hpp
##
## Create Random.cpp
##
cat >Random.cpp <<END_Random.cpp
#include "Random.hpp"
#include <vector>
#include <stdlib.h>
double Random::get_value()
{
std::vector<double> list( numValues );
for (std::vector<double>::iterator i = list.begin(); i != list.end(); ++i)
*i = rand();
return average_values( &list[0], list.size() );
}
END_Random.cpp
##
## Create main.cpp
##
cat >main.cpp <<END_main.cpp
#include "FileReader.hpp"
#include "Random.hpp"
int main( int argc, char* argv[] )
{
Random r( 100 );
printf( "<random>: %f\n", r.get_value() );
for (int i = 1; i < argc; ++i)
{
FileReader f( argv[i] );
printf("%s: %f\n", argv[i], f.get_value());
}
return 0;
}
END_main.cpp
##
## Create Makefile
##
cat >Makefile <<END_Makefile
OBJS = FileReader.o Random.o main.o
CXX = g++-3.3
main: \$(OBJS)
\$(CXX) -o \$@ \$?
END_Makefile
##
## Compile and link
##
make