2011-06-08 47 views
28

我剛學C++(第一天在看它,因爲我1周的夏令營年前開始)「富」不是在這個範圍內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 

集成和總和都應該是功能

這裏是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?

+0

您需要聲明一個函數,然後才能用C++調用它。另外,更喜歡'M_E'到'2.71828 ...' – Nemo 2011-06-08 18:04:01

回答

42

在C++中,你應該聲明函數,然後才能使用它們。在您的代碼中integrate在第一次撥打至integrate之前未被聲明。 sum同樣適用。因此錯誤。重新排序您的定義,以便函數定義在對該函數的第一次調用之前,或爲每個函數引入[forward]非定義聲明。

此外,在C++的no-no中定義頭文件中的外部非內聯函數。你的定義SkewNormalEvalutatable::SkewNormalEvalutatable,getSkewNormalintegrate等沒有業務在頭文件中。

另外SkewNormalEvalutatable e(); C++聲明聲明瞭一個函數e,而不是像你似乎假設的對象e。簡單的SkewNormalEvalutatable e;將聲明一個默認構造函數初始化的對象。

此外,收到的integrate(和sum最後一個參數通過值作爲Evaluatable類型的對象。這意味着試圖通過SkewNormalEvalutatable作爲integrate的最後一個參數將導致SkewNormalEvalutatable被切片爲Evaluatable。多態性不會因此而起作用。如果你想要多態行爲,你必須通過引用或者通過指針來接收這個參數,而不是通過值。

+1

你或許還可以提到'SkewNormalEvalutatable e();'是錯誤的,不會創建任何對象。 – Naveen 2011-06-08 18:07:45

+0

太棒了:D謝謝!我把它放在一個頭文件中,因爲我不確定如何使用多個文件,頭文件看起來更直截了當。 我應該有另一個名爲「SkewNormal.cpp」的文件並在那裏定義functiosn嗎? – 2011-06-08 18:12:17

+0

@Somanayr:通常就是這樣做的。你把函數的非定義*聲明放到頭文件中。 *定義*進入.cpp文件。 – AnT 2011-06-08 18:15:19

5

通常,在調用C++函數之前,必須先聲明它們。所以有時的getSkewNormal()定義之前,編譯器需要看到的聲明:

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

大多人做的是把所有的聲明()在頭文件,並把實際的編碼 - 定義的功能和方法 - 分成一個單獨的源文件(*.cc*.cpp)。這整齊地解決了需要聲明所有功能的問題。

7

在C++中,你的源文件通常在一次傳遞中從上到下進行解析,所以任何變量或函數都必須先聲明才能使用。有一些例外情況,例如在類定義中內聯定義函數時,但代碼並非如此。

上移的integrate定義中的一個上述對getSkewNormal,或添加上述getSkewNormal前向聲明:

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

這同樣適用於sum