‘pippo’ non è stato dichiarato in questo ambito c ++

Sto solo imparando il c ++ (il primo giorno a guardarlo da quando ho fatto un corso estivo di 1 settimana anni fa)

Stavo convertendo un programma su cui sto lavorando in Java in C ++:

#ifndef ADD_H #define ADD_H #define _USE_MATH_DEFINES #include  #include  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 

Gli errori erano:

 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 

Sia l’integrazione che la sum sono entrambe funzioni

Ecco il codice Java, più o meno lo stesso:

 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/. * © 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/. * © 2001 Marty Hall and Larry Brown; * may be freely used or adapted. */ public static interface Evaluatable { public double evaluate(double value); } 

Sono sicuro che sia qualcosa di molto semplice

Inoltre, come posso chiamare

 getSkewNormal(double skewValue, double x) 

Da un file esterno a SkewNormal.h?

In C ++ devi dichiarare le funzioni prima di poterle usare. Nel tuo codice l’ integrate non viene dichiarata prima del punto della prima chiamata da integrate . Lo stesso vale per la sum . Quindi l’errore. O riordinare le definizioni in modo che la definizione della funzione preceda la prima chiamata a quella funzione, oppure introdurre una dichiarazione [forward] non-definente per ciascuna funzione.

Inoltre, definisce funzioni esterne non inline nei file di intestazione in un no-no in C ++. Le tue definizioni di SkewNormalEvalutatable::SkewNormalEvalutatable , getSkewNormal , integrate ecc. Non hanno business nel file di intestazione.

Anche SkewNormalEvalutatable e(); la dichiarazione in C ++ dichiara una funzione e , non un object e come sembri supporre. Il semplice SkewNormalEvalutatable e; dichiarerà un object inizializzato dal costruttore predefinito.

Inoltre, si riceve l’ultimo parametro di integrate (e di sum ) per valore come object di tipo Evaluatable . Ciò significa che il tentativo di passare a SkewNormalEvalutatable come ultimo argomento di integrate comporterà il SkewNormalEvalutatable di Evaluatable a Evaluatable . Il polimorfismo non funzionerà per questo. Se si desidera un comportamento polimorfico, è necessario ricevere questo parametro per riferimento o per puntatore, ma non per valore.

In C ++, i tuoi file sorgente vengono solitamente analizzati dall’alto verso il basso in un singolo passaggio, quindi qualsiasi variabile o funzione deve essere dichiarata prima di poter essere utilizzata. Ci sono alcune eccezioni a questo, come quando si definiscono le funzioni in linea in una definizione di class, ma non è il caso del codice.

Spostare la definizione di integrate sopra quella per getSkewNormal o aggiungere una dichiarazione getSkewNormal sopra getSkewNormal :

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

Lo stesso vale per la sum .

In generale, le funzioni C ++ devono essere dichiarate prima di chiamarle. Quindi prima della definizione di getSkewNormal() , il compilatore deve vedere la dichiarazione:

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

Principalmente ciò che le persone fanno è mettere tutte le dichiarazioni ( solo ) nel file di intestazione e inserire il codice effettivo – le definizioni delle funzioni e dei metodi – in un file sorgente separato ( *.cc o *.cpp ). Questo risolve in modo chiaro il problema di dover dichiarare tutte le funzioni.