Bagaimana saya bisa melewatkan objek sebagai parameter ke suatu fungsi?

8

Saya membuat game kecil, dan ingin menyimpan skor tinggi. Saya membuat kelas Skor Tinggi di bagian atas file sketsa, seperti ini:

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

Sekarang. Di dekat bagian bawah sketsa, saya memiliki fungsi yang saya ingin mengambil objek Highscore sebagai parameter, tetapi kompiler tidak akan membiarkan saya. Contoh:

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

Kesalahan kompilasi adalah sebagai berikut:

sketch.ino: 19: 21: error: variabel atau bidang 'writeHighscore' dinyatakan batal
sketch.ino: 19: 21: kesalahan: 'Skor tinggi' tidak dideklarasikan dalam lingkup ini
sketch.ino: Dalam fungsi 'void setup ()':
sketch.ino: 64: 20: error: 'writeHighscore' tidak dinyatakan dalam lingkup ini

Setelah mengubah tipe parameter ke String, int atau apa pun, semua kesalahan hilang. Saya dapat membuat objek Highscore DI DALAM writeHighscore()fungsi, tetapi bagaimana saya bisa meneruskan objek ke sana?

Sunting 1 - Pembuatan objek

Highscore hs = Highscore("John", 975);
Serial.println(hs.toString()); // Prints "John - 975" as expected
writeHighscore(hs); // Error
krystah
sumber
dapatkah Anda memposting kode tempat Anda membuat objek Skor Tinggi?
Omer
Termasuk kode pembuatan objek.
krystah
2
Saya pikir masalahnya adalah beberapa braket yang hilang. Karena tidak ada kode lengkap, saya bisa menebak dan melihat: 1) setup () harus batal setup () . Tetapi harus menghasilkan peringatan C ++. 2) Melewati parameter kelas memaksa penyalinan objek ketika prosedur dipanggil. gcc juga harus menghasilkan peringatan jika copy constructor tidak ada. Gunakan: void writeHighscore (Highscore & hs) atau void writeHighscore (Highscore * hs) Salin snipet yang dapat dikompilasi dalam posting Anda.
TMa
Seperti yang dinyatakan dalam pertanyaan awal, dengan mengubah parameter Highscore oleh, katakanlah, String atau int, kesalahan hilang, tidak ada tanda kurung yang hilang. Saya juga sudah mencoba &hspendekatan sebelum menulis posting, serta melewati pointer writeHighscore(&hs)-> void writeHighscore(Highscore *hs)tetapi tidak berhasil.
krystah
Silakan kirim kode sumber lengkap, jika tidak, nomor baris dalam kesalahan kompilasi tidak ada gunanya.
jfpoilpret

Jawaban:

6

Anda melakukan semuanya dengan benar, tetapi Anda harus memindahkan kelas di luar file .ino Anda agar ini berfungsi. Saya tidak yakin mengapa arduino IDE membuat Anda melakukan ini (lihat edit), tetapi itu adalah sesuatu yang pernah saya alami sebelumnya.

Saya baru saja menguji ini, dan memindahkan deklarasi kelas di luar ino dan ke file header di folder proyek membuatnya mengkompilasi dengan benar. Ingatlah untuk memasukkan header yang Anda buat di ino dan ke #include "Arduino.h"dalam header untuk mendapatkan akses ke "String" lagi.

Secara teknis, hanya deklarasi maju dari kelas yang perlu berada di file yang berbeda.

Edit:

Saya relatif yakin apa yang terjadi adalah IDE menghasilkan deklarasi maju untuk semua fungsi Anda tetapi tidak kelas, yang ditempatkan sebelum definisi kelas Anda. Ini berarti bahwa melanggar fungsi regex menggunakan IDE dengan dummy "throw ()" memperbaiki masalah Anda. sebagai contoh:

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

harus bekerja dengan baik (itu bekerja untuk saya)

BrettAM
sumber
2

Ini adalah contoh klasik dari IDE yang "membantu" Anda dengan membuat prototipe fungsi, dan tidak melakukannya dengan sangat baik. Kode contoh untuk direproduksi:

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
}

Ini memberikan kesalahan:

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

Jika Anda melihat output dari preprocessor IDE (Anda dapat melakukan ini dengan menghidupkan kompilasi verbose, dan mencari tahu nama file yang sebenarnya dikompilasi) Anda melihat ini:

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

Bagian yang penting adalah:

void writeHighscore(Highscore hs);

sebelum tempat kelas dideklarasikan.


Anda dapat memperbaiki kesalahan hanya dengan membuat prototipe fungsi Anda sendiri seperti ini:

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

Sekarang kompilasi tanpa kesalahan. Ini mendeteksi prototipe fungsi Anda sendiri , dan karena itu tidak menghasilkan sendiri. Beberapa baris pertama dari file yang dihasilkan sekarang:

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

Prototipe yang meresahkan itu telah hilang.

Nick Gammon
sumber