Подтвердить что ты не робот

'foo' не был объявлен в этой области С++

Я просто изучаю С++ (первый день смотрел на него, так как я брал 1 недельный летний лагерь несколько лет назад)

Я конвертировал программу, над которой я работаю в Java на С++:

#ifndef ADD_H
#define ADD_H
#define _USE_MATH_DEFINES
#include <iostream>
#include <math.h>

using namespace std;

class Evaluatable {
public:
  virtual double evaluate(double x);
};

class SkewNormalEvalutatable : Evaluatable{
public:
  SkewNormalEvalutatable();
  double evaluate(double x){
    return 1 / sqrt(2 * M_PI) * pow(2.71828182845904523536, -x * x / 2);
  }
};

SkewNormalEvalutatable::SkewNormalEvalutatable()
{
}

double getSkewNormal(double skewValue, double x)
{
  SkewNormalEvalutatable e ();
  return 2 / sqrt(2 * M_PI) * pow(2.71828182845904523536, -x * x / 2) * integrate(-1000, skewValue * x, 10000, e);
}

// double normalDist(double x){
//   return 1 / Math.sqrt(2 * Math.PI) * Math.pow(Math.E, -x * x / 2);
// }

double integrate (double start, double stop,
                                     int numSteps, 
                                     Evaluatable evalObj)
{
  double stepSize = (stop - start) / (double)numSteps;
  start = start + stepSize / 2.0;
  return (stepSize * sum(start, stop, stepSize, evalObj));
}

double sum (double start, double stop,
                               double stepSize,
                               Evaluatable evalObj)
{
  double sum = 0.0, current = start;
  while (current <= stop) {
    sum += evalObj.evaluate(current);
    current += stepSize;
  }
  return(sum);
}

// int main()
// {
//   cout << getSkewNormal(10.0, 0) << endl;
//   return 0;
// }
#endif

Ошибки были:

SkewNormal.h: In function 'double getSkewNormal(double, double)' :
SkewNormal.h: 29: error: 'integrate' was not declared in this scope
SkewNormal.h: In function 'double integrate(double, double, int, Evaluatable)':
SkewNormal.h:41: error: 'sum' was not declared in this scope

Интеграция и сумма должны быть функциями

Вот код Java, более или менее тот же:

public static double negativelySkewed(double skew, int min, int max){
    return randomSkew(skew) * (max - min) + min;
}

public static double randomSkew(final double skew){
    final double xVal = Math.random();
    return 2 * normalDist(xVal) * Integral.integrate(-500, skew * xVal, 100000, new Evaluatable() {

        @Override
        public double evaluate(double value) {
            return normalDist(value);
        }
    });
}

public static double normalDist(double x){
    return 1 / Math.sqrt(2 * Math.PI) * Math.pow(Math.E, -x * x / 2);
}

/** A class to calculate summations and numeric integrals. The
 *  integral is calculated according to the midpoint rule.
 *
 *  Taken from Core Web Programming from 
 *  Prentice Hall and Sun Microsystems Press,
 *  http://www.corewebprogramming.com/.
 *  &copy; 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted. 
 */

public static class Integral {
  /** Returns the sum of f(x) from x=start to x=stop, where the
   *  function f is defined by the evaluate method of the 
   *  Evaluatable object.
   */

  public static double sum(double start, double stop,
                           double stepSize,
                           Evaluatable evalObj) {
    double sum = 0.0, current = start;
    while (current <= stop) {
      sum += evalObj.evaluate(current);
      current += stepSize;
    }
    return(sum);
  }

  /** Returns an approximation of the integral of f(x) from 
   *  start to stop, using the midpoint rule. The function f is
   *  defined by the evaluate method of the Evaluatable object.
   */

  public static double integrate(double start, double stop,
                                 int numSteps, 
                                 Evaluatable evalObj) {
    double stepSize = (stop - start) / (double)numSteps;
    start = start + stepSize / 2.0;
    return(stepSize * sum(start, stop, stepSize, evalObj));
  }
}

/** An interface for evaluating functions y = f(x) at a specific
 *  value. Both x and y are double-precision floating-point 
 *  numbers.
 *
 *  Taken from Core Web Programming from 
 *  Prentice Hall and Sun Microsystems Press,
 *  http://www.corewebprogramming.com/.
 *  &copy; 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted. 
 */
public static interface Evaluatable {
      public double evaluate(double value);
}

Я уверен, что это что-то очень простое

Также, как мне позвонить

getSkewNormal(double skewValue, double x)

Из файла вне SkewNormal.h?

4b9b3361

Ответ 1

В С++ вы должны объявлять функции, прежде чем сможете их использовать. В вашем коде integrate не объявляется до точки первого вызова integrate. То же самое относится к sum. Отсюда и ошибка. Либо измените порядок своих определений, чтобы определение функции предшествовало первому вызову этой функции, либо вводило декларацию [форвард], не определяющую для каждой функции.

Кроме того, определение внешних не-встроенных функций в заголовочных файлах в no-no в С++. Ваши определения SkewNormalEvalutatable::SkewNormalEvalutatable, getSkewNormal, integrate и т.д. Не состоят в заголовке файла.

Также объявление SkewNormalEvalutatable e(); в С++ объявляет функцию e, а не объект e, как вы, кажется, предполагаете. Простой SkewNormalEvalutatable e; объявит объект, инициализированный конструктором по умолчанию.

Также вы получаете последний параметр integratesum) по значению как объект типа Evaluatable. Это означает, что попытка передать SkewNormalEvalutatable в качестве последнего аргумента integrate приведет к тому, что SkewNormalEvalutatable будет нарезано до Evaluatable. Из-за этого полиморфизм не будет работать. Если вам требуется полиморфное поведение, вы должны получить этот параметр по ссылке или указателем, но не по значению.

Ответ 2

В С++ исходные файлы, как правило, анализируются сверху вниз за один проход, поэтому любая переменная или функция должны быть объявлены до их использования. Есть некоторые исключения из этого, например, при определении функций inline в определении класса, но это не относится к вашему коду.

Переместите определение integrate над тем, что указано для getSkewNormal, или добавьте переднее объявление выше getSkewNormal:

double integrate (double start, double stop, int numSteps, Evaluatable evalObj);

То же самое относится к sum.

Ответ 3

В общем, в С++ функции должны быть объявлены до их вызова. Поэтому перед определением getSkewNormal() компилятор должен увидеть объявление:

double integrate (double start, double stop, int numSteps, Evaluatable evalObj);

В основном то, что делают люди, помещают все объявления (только) в файл заголовка и помещают фактический код - определения функций и методов - в отдельный файл источника (*.cc или *.cpp), Это аккуратно решает проблему необходимости всех объявляемых функций.