【问题标题】:'foo' was not declared in this scope c++'foo' 未在此范围内声明 c++
【发布时间】:2011-06-08 18:00:45
【问题描述】:

我只是在学习 c++(几年前我参加了为期一周的夏令营后的第一天)

我正在将我正在使用 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

Integrate 和 sum 都应该是函数

这里是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 之外的文件?

【问题讨论】:

  • 您需要先声明一个函数,然后才能在 C++ 中调用它。另外,比起2.71828...,更喜欢M_E

标签: c++ function


【解决方案1】:

在 C++ 中,您应该先声明函数,然后才能使用它们。在您的代码中,integrate 未在第一次调用 integrate 之前声明。这同样适用于sum。因此错误。要么重新排序你的定义,使函数定义在第一次调用该函数之前,要么为每个函数引入一个 [forward] 非定义声明。

此外,在 C++ 中禁止在头文件中定义外部非内联函数。您对SkewNormalEvalutatable::SkewNormalEvalutatablegetSkewNormalintegrate 等的定义在头文件中没有任何业务。

C++ 中的 SkewNormalEvalutatable e(); 声明还声明了一个函数 e,而不是您似乎假设的对象 e。简单的SkewNormalEvalutatable e; 会声明一个由默认构造函数初始化的对象。

此外,您会收到integrate(和sum)的最后一个参数按值作为Evaluatable 类型的对象。这意味着尝试将SkewNormalEvalutatable 作为integrate 的最后一个参数传递将导致SkewNormalEvalutatable 被分割为Evaluatable。因此,多态性将不起作用。如果你想要多态行为,你必须通过引用或指针来接收这个参数,而不是通过值。

【讨论】:

  • 您可能还提到SkewNormalEvalutatable e (); 是错误的,不会创建任何对象。
  • 太棒了:D 谢谢!我把它放在一个头文件中,因为我不确定如何使用多个文件,而且头文件看起来更简单。我应该有另一个名为“SkewNormal.cpp”的文件并在那里定义函数吗?
  • @Somanayr:这就是通常的做法。您将函数的非定义 declarations 放入头文件中。 定义进入 .cpp 文件。
  • 介意我再问一个问题吗?我的 main.cpp 文件 (pastie.org/private/oifaxdkebrsi1oqofn0ea) 在编译时给了我一个错误:main.cpp:7:undefined reference to 'getSkewNormal(double,double)'。你能告诉我这是什么/如何解决它吗?我将函数移到 SkewNormal.cpp (pastie.org/private/4n8cys2zpr2bfw3brucsg) 中,只是在 SkewNormal.h (pastie.org/private/1g7c66xjfd3qu6idfxmwa) 中声明
  • @Somanayr:现在您的程序包含两个源文件 - main.cppSkewNormal.cpp。您必须编译这两个文件并将结果(对象文件)链接在一起。显然,您要么根本没有编译SkewNormal.cpp,要么没有将其编译结果链接到最终程序中。你用的是什么编译器?
【解决方案2】:

在 C++ 中,您的源文件通常在一次传递中从上到下解析,因此任何变量或函数都必须在使用前声明。有一些例外情况,例如在类定义中内联定义函数时,但您的代码并非如此。

要么将integrate 的定义移到getSkewNormal 的定义之上,要么在getSkewNormal 之上添加一个前向声明:

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

这同样适用于sum

【讨论】:

    【解决方案3】:

    通常,在 C++ 中,函数必须在调用之前声明。所以在getSkewNormal()的定义之前的某个时候,编译器需要看到声明:

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

    人们所做的大多是将所有的声明(only)放在头文件中,并放入实际的代码——函数和方法的定义——到单独的源文件(*.cc*.cpp)中。这巧妙地解决了需要声明所有函数的问题。

    【讨论】:

      猜你喜欢
      • 2010-12-17
      • 1970-01-01
      • 2021-07-17
      • 2015-08-21
      • 2015-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多