Как объявить и создать экземпляры класса как атрибуты класса - PullRequest
0 голосов
/ 27 мая 2020

Я разрабатываю проект Arduino, который использует несколько датчиков, поэтому мне нужно создать классы для абстрагирования каждой функции датчика, чтобы сделать его масштабируемым и простым в обслуживании.

Я должен сказать, что я ' m не очень опытен в C ++, но я отчасти владею Java, а также некоторыми шаблонами и методами, которые могут быть применены к широкому спектру языков.

Итак, каждый датчик расширяет функциональность абстрактного класса (как Вы, наверное, догадались, с именем Sensor) и определяет, как методы void setup() и T get() должны работать для каждой реализации.

В результате каждая реализация будет содержать экземпляр для базовых c класс своей библиотеки датчиков, чтобы делать показания всякий раз, когда вызывается метод T get(), но я не могу найти приемлемого решения для этой идеи, так как кажется, что я не могу понять конструкторы C ++ (даже после большого количества время, потраченное на исследования в Google и другие вопросы StackOverflow), потому что я не могу:

#include <HX711_ADC.h>
HX711_ADC loadCell;
uint8_t dout = 4;
uint8_t sck = 5;

void setup() {
     loadCell = HX711_ADC( dout, sck ); // Exception
     loadCell( dout, sck ); // Exception
}

dout a nd sck объявлены uint8_t как объявленные типы для его конструктора, как показано в HX711_AD C .h

Любая идея будет принята с благодарностью.

Ответы [ 3 ]

0 голосов
/ 27 мая 2020

HX711_ADC loadCell; создает объект с конструктором по умолчанию, то есть без аргументов.

Вы можете передавать такие аргументы:

#include <HX711_ADC.h>
const uint8_t dout = 4;
const uint8_t sck = 5;
HX711_ADC loadCell( dout, sck );

void setup() {
    loadCell.begin();
}
0 голосов
/ 27 мая 2020

Глобальные переменные мерзки. Сведите их к минимуму.

Я считаю, что лучше всего хранить всю систему в классе, поэтому:

C ++ 11

class MySystem {
  constexpr uint8_t lc_dout = 4;
  constexpr uint8_t lc_sck = 5;
  HX711_ADC loadCell{lc_dout, lc_sck};
  //...
public:
  MySystem() { /* initialization - additional */ }
  void loop() { /* the main loop */ }
};

C ++ 98

Это только для справки. Arduino поддерживает современный язык C ++ (хотя по большей части это не стандартная библиотека).

class MySystem {
  enum { lc_dout = 4, lc_sck = 5 };
  HX711_ADC loadCell;
  //...
public:
  MySystem() : loadCell(lc_dout, lc_sck)
  {  /* initialization - additional */ }
  void loop() { /* the main loop */ }
};

Используйте

Затем вам понадобится способ иметь переменную, в которой вы можете создать экземпляр система в момент вашего выбора - таким образом, вам нужно объединение:

union System {
  bool dummy;
  MySystem tem;
};

System sys; // the only global variable

Затем оно создается в setup() и выполняется в loop():

void setup() {
  new (&sys.tem) MySystem(); // constructs the instance
}

void loop() {
  sys.tem.loop();
}
0 голосов
/ 27 мая 2020

Как указано в ответах на этот вопрос, в C ++ невозможно объявить переменную без ее создания, поэтому я попытался создать указатель на переменную HX711_ADC и назначить экземпляр позже в метод void setup(). Итак, решение моей собственной проблемы:

#include <HX711_ADC.h>
HX711_ADC* loadCell;
uint8_t dout = 4;
uint8_t sck = 5;

void setup() {
     loadCell = new HX711_ADC( dout, sck );
}

Он компилируется без исключения исключений, но я не уверен, что это лучшее решение ... в любом случае, я оставляю его здесь вместо удалить его на случай, если кто-то сочтет это полезным.

[РЕДАКТИРОВАТЬ] На основе Reinstate Monica ответ Мне удалось создать масштабируемую систему, в результате следующие классы в качестве примера:

#include <HX711_ADC.h>

template<typename T>
class Sensor
{
public:
    Sensor(int _id) : id(_id) {};
    virtual void setup() = 0;
    virtual T get() = 0;
protected:  
    int id;
};

class WeightSensor: public Sensor<float>
{
public:
    WeightSensor(int id, uint8_t dout, uint8_t sck) : Sensor<float>(id), sensor(dout, sck) {  }
    void setup();
    float get();
private:
    HX711_ADC sensor;
};

inline void WeightSensor::setup()
{
    sensor.start(2000);
    sensor.setCalFactor(-41.95);
    sensor.begin();
}

inline float WeightSensor::get() {
    return sensor.getData();
}
...