'foo' не был объявлен в этой области c ++ - PullRequest
31 голосов
/ 08 июня 2011

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

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

#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?

Ответы [ 3 ]

47 голосов
/ 08 июня 2011

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

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

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

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

8 голосов
/ 08 июня 2011

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

Либо переместите определение integrate выше определения для getSkewNormal, либо добавьтепредварительное заявление выше getSkewNormal:

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

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

5 голосов
/ 08 июня 2011

Как правило, в C ++ функции должны быть объявлены до их вызова. Так что когда-нибудь перед определением getSkewNormal() компилятор должен увидеть объявление:

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...