オブジェクトをパラメーターとして関数に渡すにはどうすればよいですか?


8

小さなゲームを作っていて、ハイスコアを保存したい。次のように、スケッチファイルの先頭にHighscoreクラスを作成しました。

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

今。スケッチの下部近くに、Highscoreオブジェクトをパラメーターとして取りたい関数がありますが、コンパイラーでは許可されません。例:

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

コンパイルエラーは次のとおりです。

sketch.ino:19:21:エラー:変数またはフィールド 'writeHighscore'がvoidを宣言しました
sketch.ino:19:21:エラー: 'Highscore'がこのスコープで宣言されていませんでした
sketch.ino:関数 'void setup()':
sketch.ino:64:20:エラー: 'writeHighscore'はこのスコープで宣言されていません

パラメータタイプをString、intなどに変更すると、すべてのエラーがなくなります。writeHighscore()関数内でHighscoreオブジェクトを作成できますが、それにオブジェクトを渡すにはどうすればよいですか?

編集1-オブジェクトの作成

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

Highscoreオブジェクトを作成するコードを投稿できますか?
オメール2014年

オブジェクト作成コードが含まれています。
krystah 2014年

2
問題は、ブラケットの欠落などです。完全なコードはないので、推測して確認できます。1) setup()void setup()である必要があります。ただし、C ++の警告/エラーが生成されるはずです。2)クラスパラメータを渡すと、プロシージャが呼び出されたときにオブジェクトが強制的にコピーされます。コピーコンストラクタがない場合、gccは警告も生成する必要があります。使用:void writeHighscore(Highscore&hs)またはvoid writeHighscore(Highscore * hs) コンパイル可能なスニペットを投稿にコピーします。
TMa

元の質問で述べたように、たとえばStringまたはintによってHighscoreパラメーターを変更することにより、エラーはなくなり、括弧が欠落することはありません。私はまた&hs、投稿を書く前に、ポインタを渡すだけでなく、アプローチも試しましたwriteHighscore(&hs)-> void writeHighscore(Highscore *hs)が、役に立ちませんでした。
krystah 2014年

完全なソースコードを投稿してください。そうでない場合、コンパイルエラーの行番号は無意味です。
jfpoilpret 2014年

回答:


6

すべてが正しく行われていますが、これを機能させるには、クラスを.inoファイルの外に移動する必要があります。 なぜarduino IDEがこれを行うのかわかりません (編集を参照)、しかしそれは私が以前に遭遇したものです。

これをテストしました。クラス宣言をinoの外に移動し、プロジェクトフォルダーのヘッダーファイルに移動すると、正しくコンパイルされます。作成したヘッダーをinoとヘッダーに含めて、#include "Arduino.h"「String」に再びアクセスできるようにしてください。

技術的には、クラスの前方宣言のみを別のファイルに含める必要があります。

編集:

IDEがクラス定義の前に配置されているクラスではなく、すべての関数の前方宣言を生成していることは比較的確実です。つまり、IDEが使用する関数の正規表現をダミーの「throw()」で壊すことで問題が解決します。例えば:

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

うまく機能するはずです(私にとってはうまくいきました)


2

これは、関数プロトタイプを生成することによってIDEを「支援」するIDEの典型的な例であり、うまく機能しません。再現するサンプルコード:

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
}

これはエラーになります:

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

IDEプリプロセッサの出力を見ると(詳細なコンパイルをオンにして、実際にコンパイルしているファイルの名前を見つけることでこれを行うことができます)、次のようになります。

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

重要な部分は、それが置くことです:

void writeHighscore(Highscore hs);

クラスが宣言される前


次のように独自の関数プロトタイプを生成するだけでエラーを修正できます。

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

エラーなしでコンパイルできるようになりました。独自の関数プロトタイプを検出するため、独自の関数プロトタイプは生成しません。生成されたファイルの最初の数行は次のとおりです。

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

その厄介なプロトタイプはなくなりました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.