Сделать компонент класса ссылкой на массив
- Войдите на сайт для отправки комментариев
Пнд, 17/07/2017 - 16:43
Для того, чтобы напрямую работать с "внешней" переменной (в данном примере массив out_pins) в качестве аргумента функции мы передаем ссылку на начало переменной
void pinController::SetPinOn(byte (&out_pins)[PINS_OUT_COUNT])
А вот как сделать такой массив компонентом класса ?
Строка вида:
class pinController
{
public: (&out_pins)[PINS_OUT_COUNT];
Работать не будет.
Какой в данном случае должен быть синтаксис ?
http://arduino.ru/forum/programmirovanie/klassy-arduino-po-qwone-dlya-chainikov
Ну отсюда и далее -Операция []. Запись
a[b]всегда эквивалентна*(a + b)(напомню, что мы не рассматриваем переопределенияoperator[]и других операций)...ПС: И в Си лучше использовать указатели, потом создавать в куче аналог массива.
Ну отсюда и далее -Операция []. Запись
a[b]всегда эквивалентна*(a + b)(напомню, что мы не рассматриваем переопределенияoperator[]и других операций)...Вот мне нужно обратное, а именно:
Т.е. в инициализации объекта класса должно быть что-то вроде :
Опять вы все перепутали. Есть ссылки , а есть указатели. Есть команда объявления указателя, а есть разыменование. В общем читате БИБЛИЮ http://cpp.com.ru/kr_cbook/ch5kr.html
Ок, спасибо. Вот так шикарно для понимания )
Вот такой ещё момент :
Вопрос: При этом получили:
1.bb и aaa имеют одинаковый адрес (фактически одна переменная)
или
2.по адресу содержимого переменной bb записали значение переменной aaa ? (фактически две разных переменнных с одинаковым значением)
Дополнительный вопрос : фактически указатель (в памяти) - это такая же переменная, как и все остальные ?
указатель (в памяти) - это такая же переменная, как и все остальные.
int a; - целое
int b; - целое
int *address; - адрес переменной, которая хранит в себе целое
address = &a; - address теперь хранит адрес переменной a
*address = 5; - кабутто а=5
address = &b; - address теперь содержит адрес переменной b
*address = a; теперь значение b == 5; то же самое, кабутто b=a;
без звездочки это адрес, со звездочкой - значение по этому адресу.
Дополнительный вопрос : фактически указатель (в памяти) - это такая же переменная, как и все остальные ?
Что такое переменная ? Это место в памяти куда записывают значания. Указатель это место в памяти куда записывают адресс места памяти по которому можно записисать или считать данные. Разумеется есть и такое явление указатель на указатель. Ну и так далее. Вообще программирование на языках высокого уровня это подмена понятий. На компьютере есть только память организованая в виде ячеек памяти с адресами и все. Запись int a; выделить ячейку памяти int. Так a это тоже указатель, но не доступный пользовотелю. Но в Си выкрутились из этого . int *pnt=&a; И теперь у нас есть адресс на эту ячейку. Можно записать и так int &b=a; но здесь мы не получили адресс на эту ячейку. Мы просто получили еще одно название этой ячейки, а адресс на эту ячейку осталься не доступным.
Для того, чтобы напрямую работать с "внешней" переменной (в данном примере массив out_pins) в качестве аргумента функции мы передаем ссылку на начало переменной
А вот как сделать такой массив компонентом класса ?
Строка вида:
class pinController { public: (&out_pins)[PINS_OUT_COUNT];Работать не будет.
Какой в данном случае должен быть синтаксис ?
Главный вопрос: зачем?
Зачем сделать такой(внешний) массив компонентом класса?
(замечу что это возможно)
Зачем сделать такой(внешний) массив компонентом класса?
Чтобы не таскать этот массив сквозь все остальные классы. Экономия памяти, времени и т.д.
У меня десятка 2 датчиков и столько же управляемых устройств. Пишу "мозг"=модель, если по MVC. Он принимает решение на основе входных данных. Никаких включения/получения данных в нем быть не должно, кроме того, объекты этого класса будут работать параллельно, соответственно должны иметь всегда актульное состояние "пинов". Чтобы не передавать этот , в данном примере только массив (в дальнейшем тоже класс) , каждому объекту даю только ссылку на него. Получается массов един, о его обработчиков - много.
(замечу что это возможно)
Мы в детстве так играли : Знаю, но не скажу ))))
Ничего невозможного нет , спосов миллион. Сейчас мне водится как вариант - просто передача указателя в класс (в данном примере на миссив) при инициализации класса. Соответственно работа с этим указателем (массивом в памяти) внутри класса будет отражаться в этом внешнем массиве без каких-либо дополнительных манипуляций.
Но, тогда придётся переписывать часть кода - сейчас аргумент у всех ф-й разных классов именно массив, как в первом посте ) Поэтому сегодня ночью ещё поиграюсь с передачей именно массива (адресов каждого его элемента).
Второй вариант - динамическое создание копии "внешнего" массива внутри каждой функции и после её отработки - актуализация "внешнего" массива. Здесь ничего переделывать в синтаксисе не нужно, но громоздко и "глупо", т.к. "в лоб".
Чувствую, должно быть элегантное и простое решение, пока поработаем )
У меня десятка 2 датчиков и столько же управляемых устройств. Пишу "мозг"=модель, если по MVC. Он принимает решение на основе входных данных. Никаких включения/получения данных в нем быть не должно, кроме того, объекты этого класса будут работать параллельно, соответственно должны иметь всегда актульное состояние "пинов". Чтобы не передавать этот , в данном примере только массив (в дальнейшем тоже класс) , каждому объекту даю только ссылку на него. Получается массов един, о его обработчиков - много.
ну, смотри, как у меня в велосипеде сделано #410: класс логики, класс-оболочка для класса логики, который строит массив из экземпляров класса логики, аппаратно опрашивает пины кнопок и впаривает результаты опроса нужному екземпляру класса логики.
Отлично, но мне нужен "сквозной" массив и всего-то, чего "велосипед-то изобретать, когда он уже есть ? )
Отлично, но мне нужен "сквозной" массив и всего-то
ты долбоёб?
КаллоуНций как всегда . Уйди, не говнякай собой тему.
В общем более рационального, чем передача указателя на "внешний" массив каждому объекту, кто может вляеть на этот массив я не придумал.
Применительно к первому посту это будет так :
У этого способа есть недостаток - нужно программно контролировать пределы массива.
Прогнал автозаменой с регуляркой исходники, вроде ничего не отвалилось )
Всем спасибо за участие, даже дурачкам, када ж без оных ))) !
Я так прикинул схему кода
/**/ //------------------------------------ // класс сенсор class Cl_sens { const byte _pin; // пин byte * const _stat;//указатель на состояние датчика public: Cl_sens(byte pin, byte * stat): _pin(pin), _stat(stat) {} void setup() { pinMode(_pin, INPUT); *_stat = digitalRead(_pin); } void loop() { *_stat = digitalRead(_pin); } }; //----------------------------------- // класс мозг class Cl_brain { byte * const _brain_array;//указатель на анализируемый массив public: Cl_brain(byte * brain_array): _brain_array(brain_array) {} void setup() { _brain_array[2] = _brain_array[0]; _brain_array[3] = _brain_array[1]; } void loop() { _brain_array[2] = _brain_array[0]; _brain_array[3] = _brain_array[1]; } }; //---------------------------------------------------- // класс исполнительный механизм class Cl_actuating_mechanism { const byte _pin; // пин byte * const _stat;//указатель на состояние механизма public: Cl_actuating_mechanism(byte pin, byte * stat): _pin(pin), _stat(stat) {} void setup() { pinMode(_pin, OUTPUT); digitalWrite(_pin, * _stat); } void loop() { digitalWrite(_pin, * _stat); } }; //-------компоновка------------------------- byte Array[4] = {0, 0, // -- данные сенсора 0, 0 // -- команды на исполнительные механизмы }; Cl_sens Sens1(/*пин*/2,/*ячейка памяти*/&Array[0]); Cl_sens Sens2(/*пин*/3,/*ячейка памяти*/&Array[1]); Cl_brain Brain(/*анализируемый массив*/Array); Cl_actuating_mechanism Mech1(/*пин*/4,/*ячейка памяти*/&Array[2]); Cl_actuating_mechanism Mech2(/*пин*/5,/*ячейка памяти*/&Array[3]); //-------main()----------------------------- void setup() { Sens1.setup(); Sens2.setup(); Brain.setup(); Mech1.setup(); Mech2.setup(); } void loop() { Sens1.loop(); Sens2.loop(); Brain.loop(); Mech1.loop(); Mech2.loop(); }ПС: Хотя правильнее заменить &Array[0] на Array; &Array[1]) на (Array+1) ни и так далее.
Да, ну что Вы - сам датчик - отдельныя плата, общение с ним по Uart, их много. Вот типа этого https://www.gidroponika.su/gidroponika-svoimi-rukami.html/myopit/171-rastvornyj-uzel-dlya-gidroponiki.html
А тема исключительно для передачи "внешнего" массива "внутрь" каждого класса. Смысл такой: поступила команда "смыть унитаз". Мозг смотрит : включено наполнение унитаза, значит нет смысла его смывать, ставим в очередь, или "убиваем" эту команду, в зависимости от кучи сторонних обстоятельств.
Так же для датчиков: чтобы включить датчик - нужно подать порция раствора, смотрим - бак сухой, и в очереди команда на мойку бака. Что же делать с командой замера ? Убить, ждать мойки, может она уже не актуальна будет ?
Ардуино для прототипирования, вообще это дело нейросети, принимать такие решения на основе многих неопределенностей, она в процессе, только это уже не атмега )
Да, ну что Вы - сам датчик - отдельныя плата, общение с ним по Uart, их много.
ПС: Хотя правильнее заменить &Array[0] на Array; &Array[1]) на (Array+1) ни и так далее.
Я так и делал в начале, только пом прикинул, как передать "аморфный" объект в качестве аргумента ?
Пока выход для СИ: пердача ссылки на указатель (до этой тему я не понимал как правильно их использовать), второй аргумент , а ещё лучше в самом начале данных по указателю - тип объекта.
И тогда и унитаз может работать с датчиком и ионселективный электрод с освещением без переделки кода - самое то для нейросети .
Да последний мой скетч, он лучше выглядит так. Но массива там уже нет.
/**/ //------------------------------------ struct str_Array { bool sens1; // сенсор 1 bool sens2; // сенсор 2 bool mech1; // испол. механ 1 bool mech2; // испол. механ 2 str_Array(bool b1, bool b2, bool b3, bool b4 ): sens1(b1), sens2(b2), mech1(b3), mech2(b4) {} }; //------------------------------------ // класс сенсор class Cl_sens { const byte _pin; // пин bool *_stat;//указатель на состояние датчика public: Cl_sens(byte pin, bool * stat): _pin(pin), _stat(stat) {} void setup() { pinMode(_pin, INPUT); *_stat = digitalRead(_pin); } void loop() { *_stat = digitalRead(_pin); } }; //----------------------------------- // класс мозг class Cl_brain { struct str_Array *Array;//указатель на анализируемый массив public: Cl_brain(struct str_Array *_Array): Array(_Array) {} void setup() { Array->mech1 = Array->sens1; Array->mech2 = Array->sens2; } void loop() { Array->mech1 = Array->sens1; Array->mech2 = Array->sens2; } }; //---------------------------------------------------- // класс исполнительный механизм class Cl_actuating_mechanism { const byte _pin; // пин bool * const _stat;//указатель на состояние механизма public: Cl_actuating_mechanism(byte pin, bool * stat): _pin(pin), _stat(stat) {} void setup() { pinMode(_pin, OUTPUT); digitalWrite(_pin, * _stat); } void loop() { digitalWrite(_pin, * _stat); } }; //-------компоновка------------------------- struct str_Array Array(0, 0, // -- данные сенсора 0, 0 // -- команды на исполнительные механизмы ); Cl_sens Sens1(/*пин*/2,/*ячейка памяти*/&Array.sens1); Cl_sens Sens2(/*пин*/3,/*ячейка памяти*/&Array.sens2); Cl_brain Brain(/*анализируемый массив*/&Array); Cl_actuating_mechanism Mech1(/*пин*/4,/*ячейка памяти*/&Array.mech1); Cl_actuating_mechanism Mech2(/*пин*/5,/*ячейка памяти*/&Array.mech2); //-------main()----------------------------- void setup() { Sens1.setup(); Sens2.setup(); Brain.setup(); Mech1.setup(); Mech2.setup(); } void loop() { Sens1.loop(); Sens2.loop(); Brain.loop(); Mech1.loop(); Mech2.loop(); }А вот это :
не логичнее делать как :
Ведь boolean все равно в памати займёт байт (я не уверен, но где-то что -то мне так помнится). Кроме того исп. механизм может быть открыт не на 100%, это без каких-либо доработок позволяет использование byte - 0 выкл, 1-255 положение/сила.
А тема исключительно для передачи "внешнего" массива "внутрь" каждого класса.
массива унитазов?
А тема исключительно для передачи "внешнего" массива "внутрь" каждого класса.
массива унитазов?
Верно ! Вы чётко уловили суть задачи.
А вот это :
не логичнее делать как :
Верно ! Вы чётко уловили суть задачи.
так, в чём проблема?
так, в чём проблема?
У кого ?
У кого ?
ок. ТС ушёл в несознанку.
У кого ?
ок. ТС ушёл в несознанку.
Найдите другую тему, пожалуйста, и упражняйтесь в слабоумии там. Брысь, короче.
Найдите другую тему, пожалуйста, и упражняйтесь в слабоумии там. Брысь, короче.
назови мне одну убедительную причину, что бы я начал ходить строем.
Зачем сделать такой(внешний) массив компонентом класса?
Чтобы не таскать этот массив сквозь все остальные классы. Экономия памяти, времени и т.д.
У меня десятка 2 датчиков и столько же управляемых устройств. Пишу "мозг"=модель, если по MVC. Он принимает решение на основе входных данных. Никаких включения/получения данных в нем быть не должно, кроме того, объекты этого класса будут работать параллельно, соответственно должны иметь всегда актульное состояние "пинов". Чтобы не передавать этот , в данном примере только массив (в дальнейшем тоже класс) , каждому объекту даю только ссылку на него. Получается массов един, о его обработчиков - много.
(замечу что это возможно)
Мы в детстве так играли : Знаю, но не скажу ))))
Ничего невозможного нет , спосов миллион. Сейчас мне водится как вариант - просто передача указателя в класс (в данном примере на миссив) при инициализации класса. Соответственно работа с этим указателем (массивом в памяти) внутри класса будет отражаться в этом внешнем массиве без каких-либо дополнительных манипуляций.
Но, тогда придётся переписывать часть кода - сейчас аргумент у всех ф-й разных классов именно массив, как в первом посте ) Поэтому сегодня ночью ещё поиграюсь с передачей именно массива (адресов каждого его элемента).
Второй вариант - динамическое создание копии "внешнего" массива внутри каждой функции и после её отработки - актуализация "внешнего" массива. Здесь ничего переделывать в синтаксисе не нужно, но громоздко и "глупо", т.к. "в лоб".
Чувствую, должно быть элегантное и простое решение, пока поработаем )
Короче я понял. 1)Вам надо изучать чистый С++ - тогда работать будет на порядок стабильней, без ардуиновских костылей.
2) Делай так: передавай в функцию не массив а указатель на массив.
3) Есть и другой метод. из области ООП.
без ардуиновских костылей.
Онкель, перелогинься, сука.
2) Делай так: передавай в функцию не массив а указатель на массив.
на массив унитазов.
3) Есть и другой метод. из области ООП.
нужно звать местнага пидагога.
Короче я понял. 1)Вам надо изучать чистый С++ - тогда работать будет на порядок стабильней, без ардуиновских костылей.
Согласен. Но, конкретно для данной задачи, конкретно в данный момент это нецелесообразно. Задача решена .
2) Делай так: передавай в функцию не массив а указатель на массив.
Согласен, так и реализовал, см. выше.
3) Есть и другой метод. из области ООП.
Их много )
Виртуальное ООП...
Есть виртуальная лампочка - у неё нет свойства "горячая", т.к. виртуальная лампочка не может быть горячей.
Но про неё можно это написать.
Где-то снаружи в заметках о виртуальной лампочке.