Когда выполняются глобальные констукторы?
Прошу прощения, если это уже обсуждалось раньше, но я ничего не смог найти.
Я написал простой класс светодиодов. Для иллюстрации (на самом деле это немного сложнее), но это звучит примерно так:
class LED {
LED(byte pin);
private:
int _pin;
};
А конструктор - это просто;
LED::LED(byte pin) {
_pin = pin;
};
и я создаю глобальный экземпляр этого класса в верхней части моего кода таким образом;
LED redLED(5);
Это необходимо создать как глобальный объект, потому что (а) я не могу создать объект в функции setup(), потому что он выйдет за рамки, и (б) я не могу создать в функции loop(), потому что я не хочу создавать бесконечное количество этих объектов.
Кажется, все это работает нормально, но мне просто интересно, когда именно этот конструктор будет выполнен? Я полагаю, что это должно быть до setup()?
Ответили!
Большое спасибо всем респондентам. Поэтому при использовании Arduino IDE процесс сборки должен молча вставить процедуру main(). Я не знал, что он это делает. Я предполагаю, что в большинстве случаев вам сойдет с рук не знать, когда вызываются глобальные конструкторы.
Хорошей практикой (я думаю) является создание класса "обертка" для всех / любых внешних (или, возможно, внутренних) аппаратных устройств, подключенных к вашему arduino. И поэтому, возможно, заманчиво (но рискованно) выполнять работу инициализации в конструкторе.
Поэтому, учитывая то, что я теперь знаю, лучше создать метод "init()" для таких классов, которые могут быть вызваны из setup() . Даже если просто сделать вызов pinmode() .
Еще раз спасибо.
@Rob W, 👍2
Обсуждение3 ответа
Лучший ответ:
Глобальные конструкторы запускаются сразу после инициализации
, выполняемой кодом запуска среды выполнения C, и непосредственно перед вызовом main()
.
В двух словах, код инициализации среды выполнения C:
- выполняет ли некоторые низкоуровневые инициализации (например, настройку памяти)
- вызывает глобальные конструкторы
- вызывает
main()
, который, в свою очередь- вызывает
init()
для выполнения инициализации, специфичной для Arduino настройка вызовов()
- многократно вызывает
loop()
- вызывает
Мелкие детали, вероятно, зависят от конкретной платформы. Для плат на базе AVR они описаны в руководстве avr-libc.
Он выполняется до вызова main() (в main() вызывается
setup
(), а затем loop()
вызывается в бесконечном цикле).
Он имеет свои собственные разделы для конструкторов и деструкторов: http://beefchunk.com/documentation/sys-programming/binary_formats/elf/elf_from_the_programmers_perspective/node4.html
class LED {
private:
const byte _pin;
public:
LED(const byte pin);
};
С еще более простым к'тором:
LED::LED(const byte pin) : _pin(pin) {};
Чтобы быть немного по теме: список инициализаторов выполняется даже перед телом конструктора и, таким образом, является способом инициализации констант.
Остается вопрос, гарантировано ли это, что это работает:
class LED {
private:
const byte _pin;
public;
LED(const byte pin) : _pin(pin) {pinMode(_pin,OUTPUT);}
set(bool state) {digitalWrite(_pin, state); }
};
(Можно ли вызвать pinMode так рано или следует изобрести метод init() ? )
Мой опыт говорит : работает хорошо ...
Обратите внимание, что конструктор запускается до инициализации ядра Arduino. Вы уверены, что он хорошо работает на каждой плате Arduino? В AVR это, конечно, так, потому что pinMode ()
не зависит от готовности ядра Arduino., @Edgar Bonet
Я тестировал это только на Нано, @Rob W
- C++ против языка Arduino?
- Как использовать SPI на Arduino?
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Ошибка: expected unqualified-id before 'if'
- Что лучше использовать: #define или const int для констант?
- Функции со строковыми параметрами
- Библиотека DHT.h не импортируется
- ошибка: ожидаемое первичное выражение перед токеном ','
Re “_ процесс сборки должен автоматически вставлять процедуру main()_”: это [предоставляется основной библиотекой Arduino] (https://github.com/arduino/ArduinoCore-avr/blob/1.8.3/cores/arduino/main.cpp ). Re “_ лучше создать метод ‘init()'_”: казалось бы, ’begin()` - это каноническое имя для такого метода., @Edgar Bonet