Come posso passare un oggetto come parametro a una funzione?


8

Sto realizzando un gioco minuscolo e voglio memorizzare punteggi alti. Ho creato una classe Highscore nella parte superiore del file di schizzo, in questo modo:

class Highscore {
public:
  String name;
  int score;

  String toString() {
    return this->name + " - " + (String)score;
  }

  Highscore(String name, int score) {
    this->name = name;
    this->score = score;
  }
};

setup() { // etc

Adesso. Nella parte inferiore dello schizzo, ho una funzione che voglio prendere un oggetto Highscore come parametro, ma il compilatore non me lo consente. Esempio:

void writeHighscore(Highscore hs) {
  File f = SD.open("high.txt", FILE_WRITE);
  // Do stuff

L'errore di compattazione è il seguente:

sketch.ino: 19: 21: errore: variabile o campo 'writeHighscore' dichiarato vuoto
sketch.ino: 19: 21: errore: 'Highscore' non è stato dichiarato in questo ambito
sketch.ino: nella funzione 'void setup ()':
sketch.ino: 64: 20: errore: 'writeHighscore' non è stato dichiarato in questo ambito

Dopo aver modificato il tipo di parametro in String, int o altro, tutti gli errori scompaiono. Sono in grado di creare oggetti Highscore all'interno della writeHighscore()funzione, ma come posso passare oggetti ad essa?

Modifica 1 - Creazione dell'oggetto

Highscore hs = Highscore("John", 975);
Serial.println(hs.toString()); // Prints "John - 975" as expected
writeHighscore(hs); // Error

puoi per favore pubblicare il codice in cui crei l'oggetto Highscore?
Omer,

Incluso il codice di creazione dell'oggetto.
Krystah,

2
Penso che il problema sia qualche parentesi mancante o giù di lì. Poiché non esiste un codice completo, posso indovinare e vedere: 1) setup () dovrebbe essere void setup () . Ma dovrebbe generare un avviso / errore C ++. 2) Il passaggio del parametro di classe forza la copia dell'oggetto quando viene chiamata la procedura. gcc dovrebbe anche generare un avviso se manca il costruttore di copie. Usa: void writeHighscore (Highscore & hs) o void writeHighscore (Highscore * hs) Copia lo snipet compilabile nel tuo post.
TMa,

Come affermato nella domanda originale, modificando il parametro Highscore con, diciamo, una stringa o un int, gli errori scompaiono, non ci sono parentesi mancanti. Ho anche provato l' &hsapproccio prima di scrivere il post, oltre a passare il puntatore writeHighscore(&hs)-> void writeHighscore(Highscore *hs)ma senza risultati.
Krystah,

Si prega di inserire il codice sorgente completo, altrimenti i numeri di riga negli errori di compilazione sono inutili.
jfpoilpret,

Risposte:


6

Stai facendo tutto nel modo giusto, ma devi spostare la classe al di fuori del tuo file .ino affinché funzioni. Non sono sicuro del perché l'IDE di Arduino ti faccia fare questo (vedi modifica), ma è qualcosa che ho incontrato prima.

Ho appena provato questo, e spostare la dichiarazione di classe fuori da ino e in un file di intestazione nella cartella del progetto lo rende compilato correttamente. Ricorda solo di includere l'intestazione creata in ino e #include "Arduino.h"nell'intestazione per accedere nuovamente a "String".

Tecnicamente, solo una dichiarazione a termine della classe deve trovarsi in un file diverso.

Modificare:

Sono relativamente sicuro che ciò che sta accadendo è che l'IDE sta generando dichiarazioni anticipate per tutte le funzioni, ma non per la classe, che vengono poste prima della definizione della classe. Ciò significa che la rottura della regex della funzione utilizzata dall'IDE con un "lancio ()" fittizio risolve il problema. per esempio:

void writeHighscore(Highscore hs) throw() { ...

dovrebbe funzionare bene (ha funzionato per me)


2

Questo è un classico esempio dell'IDE che ti "aiuta" generando prototipi di funzioni e non riuscendo molto bene. Codice di esempio da riprodurre:

class Highscore {
public:
  String name;
  int score;
  String toString() {
    return this->name + " - " + (String)score;
  }

  Highscore(String name, int score) {
    this->name = name;
    this->score = score;
  }
};

void setup () { }
void loop () { }

void writeHighscore(Highscore hs) 
{
// do stuff
}

Questo dà l'errore:

sketch_jul06b:4: error: variable or field writeHighscore declared void
sketch_jul06b:4: error: Highscore was not declared in this scope

Se guardi l'output del preprocessore IDE (puoi farlo attivando la compilazione dettagliata e scoprendo il nome del file che sta effettivamente compilando) vedi questo:

#line 1 "sketch_jul06b.ino"
#include "Arduino.h"
void setup ();
void loop ();
void writeHighscore(Highscore hs);
#line 1
class Highscore {
public:
  String name;
  int score;
  String toString() {
    return this->name + " - " + (String)score;
  }

  Highscore(String name, int score) {
    this->name = name;
    this->score = score;
  }
};

void setup () { }
void loop () { }

void writeHighscore(Highscore hs) 
{
// do stuff
}

La parte importante è che ha messo:

void writeHighscore(Highscore hs);

prima dove viene dichiarata la classe.


È possibile correggere l'errore semplicemente generando il proprio prototipo di funzione in questo modo:

void writeHighscore(Highscore hs);  // function prototype
void writeHighscore(Highscore hs) 
{
// do stuff
}

Ora si compila senza errori. Rileva il proprio prototipo di funzione e quindi non genera il proprio. Le prime poche righe del file generato sono ora:

#line 1 "sketch_jul06b.ino"
#include "Arduino.h"
void setup ();
void loop ();
#line 1

Quel prototipo inquietante è sparito.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.