Como posso passar um objeto como parâmetro para uma função?


8

Estou fazendo um jogo minúsculo e quero armazenar pontuações mais altas. Eu criei uma classe Highscore na parte superior do arquivo de esboço, assim:

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

Agora. Perto da parte inferior do esboço, tenho uma função que quero usar como parâmetro um objeto Highscore, mas o compilador não me permite. Exemplo:

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

O erro de complementação é o seguinte:

sketch.ino: 19: 21: erro: variável ou campo 'writeHighscore' declarado nulo
sketch.ino: 19: 21: erro: 'Highscore' não foi declarado neste escopo
sketch.ino: Na função 'void setup ()':
sketch.ino: 64: 20: erro: 'writeHighscore' não foi declarado neste escopo

Após alterar o tipo de parâmetro para String, int ou o que for, todos os erros desaparecem. Eu sou capaz de criar objetos Highscore DENTRO da writeHighscore()função, mas como posso passar objetos para ela?

Editar 1 - Criação de objeto

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

você pode postar o código onde você cria o objeto Highscore?
Omer

Incluído o código de criação do objeto.
krystah

2
Eu acho que o problema é algum suporte ausente ou algo assim. Como não há código completo, posso adivinhar e ver: 1) setup () deve ser nulo setup () . Mas deve gerar aviso / erro em C ++. 2) O parâmetro da classe de passagem força a cópia do objeto quando o procedimento é chamado. O gcc também deve gerar um aviso se o construtor de cópias estiver ausente. Use: void writeHighscore (Highscore & hs) ou void writeHighscore (Highscore * hs) Copie o snipet compilável em sua postagem.
TMA

Como afirmado na pergunta original, alterando o parâmetro Highscore por, digamos, uma String ou um int, os erros desaparecem, não há colchetes ausentes. Eu também tentei a &hsabordagem antes de escrever o post, além de passar o ponteiro writeHighscore(&hs)-> void writeHighscore(Highscore *hs)mas sem sucesso.
krystah

Por favor, poste o código fonte completo, caso contrário, os números de linha nos erros de compilação são inúteis.
jfpoilpret

Respostas:


6

Você está fazendo tudo certo, mas precisa mover a classe para fora do seu arquivo .ino para que isso funcione. Não sei por que o IDE do arduino faz você fazer isso (veja editar), mas é algo que já encontrei antes.

Acabei de testar isso, e mover a declaração de classe para fora do ino e para um arquivo de cabeçalho na pasta do projeto faz com que ele seja compilado corretamente. Lembre-se de incluir o cabeçalho criado na ino e #include "Arduino.h"no cabeçalho para obter acesso a "String" novamente.

Tecnicamente, apenas uma declaração de encaminhamento da classe precisa estar em um arquivo diferente.

Editar:

Estou relativamente certo de que o que está acontecendo é que o IDE está gerando declarações de encaminhamento para todas as suas funções, mas não para a classe, que são colocadas antes da sua definição de classe. Isso significa que quebrar a expressão regular da função que o IDE usa com um "throw ()" simulado corrige seu problema. por exemplo:

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

deve funcionar muito bem (funcionou para mim)


2

Este é um exemplo clássico do IDE "ajudando" você a gerar protótipos de função e não fazendo muito bem. Código de exemplo para reproduzir:

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
}

Isso dá o erro:

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

Se você observar a saída do pré-processador IDE (você pode fazer isso ativando a compilação detalhada e descobrindo o nome do arquivo que está realmente compilando), verá o seguinte:

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

A parte importante é que ele coloca:

void writeHighscore(Highscore hs);

antes de onde a classe é declarada.


Você pode corrigir o erro simplesmente gerando seu próprio protótipo de função como este:

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

Agora ele compila sem erros. Ele detecta seu próprio protótipo de função e, portanto, não gera o seu próprio. As primeiras linhas do arquivo gerado são agora:

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

Esse protótipo preocupante se foi.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.