«ошибка:» A «не может быть перегружен», но в коде нет никакой перегрузки

#c #arduino

Вопрос:

Я только что получил Arduino и начал изучать C . Я решил начать с реализации простой игры «уклонение от автомобиля», присутствующей в тех очень старых ручных устройствах «9999 в 1», использующих ЖК-дисплей и кнопки. Однако я столкнулся с очень странной проблемой с кодом.

Компилятор считает , что я пытаюсь переопределить setUp и tearDown , но я не вижу, где это происходит. В буквальном смысле нет дополнительных экземпляров, кроме исходных определений функций, но именно это происходит, когда я пытаюсь скомпилировать (используя Stino для Sublime Text, если это уместно):

 Compiling lcd...
Creating C:UsersLeonardoDocumentsArduino_Buildlcdlcd.ino.cpp.o...
C:UsersLeonardoDocumentsArduino_Buildlcdlcd.ino.cpp:31: error: 'virtual void Scene::setUp(LiquidCrystal)' cannot be overloaded
C:UsersLeonardoDocumentsArduino_Buildlcdlcd.ino.cpp:25: error: with 'virtual void Scene::setUp(LiquidCrystal)'
C:UsersLeonardoDocumentsArduino_Buildlcdlcd.ino.cpp:32: error: 'virtual void Scene::tearDown(LiquidCrystal)' cannot be overloaded
C:UsersLeonardoDocumentsArduino_Buildlcdlcd.ino.cpp:26: error: with 'virtual void Scene::tearDown(LiquidCrystal)'
[Stino - Error 1]
 

Это исходный файл «игры» lcd.ino , в котором пока нет ничего об игре:

 #include "LiquidCrystal.h"

#define LEFT_BUTTON_PIN 8
#define RIGHT_BUTTON_PIN 7

#define LEFT_PRESSED B10
#define RIGHT_PRESSED B01

#define STATE_SPLASH 0
#define STATE_PLAY 1
#define STATE_SCORE 2

// LiquidCrystal display with:
// rs on pin 12
// rw on pin 11
// enable on pin 10
// d4, d5, d6, d7 on pins 5, 4, 3, 2
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);


class Scene {
    public:
    virtual void loop(byte input, LiquidCrystal lcd) {}
    virtual void setUp(LiquidCrystal lcd) {}
    virtual void tearDown(LiquidCrystal lcd) {}
};

class Splash : public Scene {
    public: void loop(byte input, LiquidCrystal lcd) {
        lcd.print("Welcome to CAR DODGE");
        lcd.print("Press LEFT to start!");
    }
};

class Game : public Scene {
    public: void loop(byte input, LiquidCrystal lcd) {
        lcd.print("HI");
    }
};

class Score : public Scene {
    public: void loop(byte input, LiquidCrystal lcd) {
        lcd.print("HI");
    }
};


byte currentMode = STATE_SPLASH;
Scene *gameModes[] = {new Splash(), new Game(), new Score()};

byte getInput() {
    bool leftSample1 = digitalRead(LEFT_BUTTON_PIN);
    bool rightSample1 = digitalRead(RIGHT_BUTTON_PIN);
    Serial.print(leftSample1);
    Serial.print(" ");
    Serial.println(rightSample1);
}

void changeGameMode(byte next) {
    gameModes[currentMode]->tearDown(lcd);
    gameModes[next]->setUp(lcd);
    currentMode = next;
}

void setup() {
    Serial.begin(9600);

    pinMode(LEFT_BUTTON_PIN, INPUT);
    pinMode(RIGHT_BUTTON_PIN, INPUT);
    lcd.begin(20, 4);

    changeGameMode(STATE_SPLASH);
}

void loop() {
    byte input = getInput();
    gameModes[currentMode]->loop(input, lcd);
    delay(150);
}
 

ИЗМЕНИТЬ: lcd.ino.cpp содержимое, которое генерируется инструментами сборки Arduino:

 #include <Arduino.h>
#include "LiquidCrystal.h"

#define LEFT_BUTTON_PIN 8
#define RIGHT_BUTTON_PIN 7

#define LEFT_PRESSED B10
#define RIGHT_PRESSED B01

#define STATE_SPLASH 0
#define STATE_PLAY 1
#define STATE_SCORE 2

// LiquidCrystal display with:
// rs on pin 12
// rw on pin 11
// enable on pin 10
// d4, d5, d6, d7 on pins 5, 4, 3, 2
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);


class Scene {
    public:

virtual void setUp(LiquidCrystal lcd);
virtual void tearDown(LiquidCrystal lcd);
byte getInput();
void changeGameMode(byte next);

virtual void loop(byte input, LiquidCrystal lcd) {}
    virtual void setUp(LiquidCrystal lcd) {}
    virtual void tearDown(LiquidCrystal lcd) {}
};

class Splash : public Scene {
    public: void loop(byte input, LiquidCrystal lcd) {
        lcd.print("Welcome to CAR DODGE");
        lcd.print("Press LEFT to start!");
    }
};

class Game : public Scene {
    public: void loop(byte input, LiquidCrystal lcd) {
        lcd.print("HI");
    }
};

class Score : public Scene {
    public: void loop(byte input, LiquidCrystal lcd) {
        lcd.print("HI");
    }
};


byte currentMode = STATE_SPLASH;
Scene *gameModes[] = {new Splash(), new Game(), new Score()};

byte getInput() {
    bool leftSample1 = digitalRead(LEFT_BUTTON_PIN);
    bool rightSample1 = digitalRead(RIGHT_BUTTON_PIN);
    Serial.print(leftSample1);
    Serial.print(" ");
    Serial.println(rightSample1);
}

void changeGameMode(byte next) {
    gameModes[currentMode]->tearDown(lcd);
    gameModes[next]->setUp(lcd);
    currentMode = next;
}

void setup() {
    Serial.begin(9600);

    pinMode(LEFT_BUTTON_PIN, INPUT);
    pinMode(RIGHT_BUTTON_PIN, INPUT);
    lcd.begin(20, 4);

    changeGameMode(STATE_SPLASH);
}

void loop() {
    byte input = getInput();
    gameModes[currentMode]->loop(input, lcd);
    delay(150);
}
 

Что я здесь упускаю?

Комментарии:

1. Это полный исходный файл lcd.ino.cpp ?

2. Не могли бы вы указать, пожалуйста, какая из строк в показанном коде является строками 25, 26, 31 и 32?

3. @JoachimPileborg Я тоже не знаю, номера строк, похоже, тоже не указаны в полном коде. Я опубликую весь файл целиком. ИЗМЕНИТЬ: теперь вопрос содержит весь файл, но номера строк вообще не имеют смысла.

4. Возможно ли, что вы ищете не тот файл или вы не сохранили файл на диск?

5. Номера строк все еще не совпадают с исходным кодом. Вы редактировали исходный код с тех пор, как получили ошибки? Вы пробовали строить снова?

Ответ №1:

Ответ может быть немного запоздалым, но;

Похоже, IDE Arduino не любит, когда функции-члены объявляются в определении класса.

Просто для ясности:

 class example {
    public:
           void function(){ /*code not here*/ };  
    private:
            int variable;
};

void example::function(){
    //code here
}  
 

Комментарии:

1. Действительно, в этом-то и была проблема! Может быть, для меня уже поздно, но я уверен, что кто — то выиграет от этого ответа!

Ответ №2:

Из справки MS C :

Виртуальные функции в базовом классе должны быть определены, если они не объявлены с использованием спецификатора pure.

Я думаю, что проблема МОЖЕТ заключаться в определении null в базовом классе. Либо сделайте объявление базового класса чистым и удалите нулевое определение, либо предоставьте диагностическое ненулевое определение.

Комментарии:

1. Но они определены. Даже если тело функции-члена пустое, это все равно означает, что функция-член будет определена.

2. @joachim Это то, чего я ожидал. Однако я не вижу никакой другой проблемы, поэтому стоит проверить, является ли это причудой компилятора/отличием от MS. Представленная ошибка относится к промежуточному файлу, содержащему объявления, за которыми следуют определения-похоже, что определение является перегрузкой. Но почему?

3. Ну, Arduino вряд ли использует компилятор Microsoft C .

4. Функции определены, так что я не думаю, что в этом проблема. Это может быть связано с тем, как сборка Arduino преобразует код, см. раздел редактирование.

Ответ №3:

В моем конкретном случае ошибка произошла из-за того, что я случайно объявил одни и те же функции несколько раз. Как только я удалил дополнительные объявления функций, проблема была устранена.

Комментарии:

1. Поскольку ваш ответ не содержит кода или деталей, комментарий был бы более уместен.