Указатель на неопределенный класс ... ?
- Войдите на сайт для отправки комментариев
Вс, 24/10/2021 - 18:23
Можно ли, и как, создать указатель на класс, если класс заранее неизвестен ?
Т.е. создать указатель на класс "вообще" ?
С заранее известными все понятно:
HardwareSerial *sp; sp = &Serial; sp->prinln("Это Serial");
А как быть если класс заранее неизвестен и может меняться программно (задаваться пользователем) ?
нельзя. Только просто указатель на "нечто" void
Жаль. В других языках это реализуемо.
Можно, конечно. В пределах разумного. Только Вы неверно формулируете задачу, потому не понимаете как её решить. Попробуйте сформулировать вопрос более чётко.
Указатель на "что-нибудь" объявляется очень просто : void *ptr; Но это жуткий говнокод и такой приём оправдан только в очень редких случаях. Чаще всего, если такое потребовалось, значит программа неверно спроектирована.
Иметь указатель на "класс вообще" вещь абсолютно бесполезная. Что Вы с ним будете делать? А вот указатель "на любой класс, у которого есть такой-то метод (такие-то методы)" - это без проблем, это общая стандартная практика. Делайте на здоровье.
Задача:
Есть кнопка, по нажатию которой выполняется какое-то заранее неизвестное действие. Какое - задается пользователем в настройках (после компиляции). Есть несколько объектов разных классов, которые могут выполнять эти действия. Пользователь выбирает объект (по его имени) и функцию в объекте (тоже по имени). Имена заданы в самом классе. После настройки, при нажатии на кнопку должна выполниться заданная функция заданного объекта. Настройки могут изменяться во время работы программы.
В смысле "на любой класс, у которого есть такой-то метод (такие-то методы)" ? Классы свои, я могу задать в них одинаковые (по имени) методы.
Номер выбранного пользователем действия (сценария) в int, и дальше свитч-кейс на кнопке, не??
В программе до десятка объектов + их функции. Количество возможных сценариев (не все практически имеют смысл) будет огромным. Но идея интересная, если не получится по-другому ....
В программе до десятка объектов + их функции. Количество возможных сценариев (не все практически имеют смысл) будет огромным. Но идея интересная, если не получится по-другому ....
Десяток объектов - фигня. Реализуйте каждый объект экземпляром класса, организуйте их в массив и будет вам щщастье.
Либо, если каждый объект уникального класса, то таки свитч-кейс
Автор, зачем такие заморочки? Если всё равно, после в настройках всё определяете. Ну определите какие то начальные условия переменных, а потом меняйте их сколько угодно. Согласен с Rumata. Хотя если это лабораторка, тогда препод попал в точку.
Каждый объект и так реализован как экземпляр класса, но классы разные, в один массив их не загонишь. Количество объектов класса тоже заранее не известно. Известно только максимально возможное значение.
В смысле "на любой класс, у которого есть такой-то метод (такие-то методы)" ? Классы свои, я могу задать в них одинаковые (по имени) методы.
Так какого рожна Вам ещё надо? Так и делайте. В чём проблема?
Или Вы не знаете как сделать указатель "на любой класс, у которого есть такой-то метод (такие-то методы)"?
Это не лабораторка :) Последнюю "лабу" я делал лет 40 назад :)
Это контроллер. Куча устройств 1-wire, RS485, плюс Bluetooth, Wi-Fi, GSM. Пользователь определяет, что делать, если датчик показывает "такую-то" температуру. То-ли включить / выключить что-то, то ли отправить СМС.
Или Вы не знаете как сделать указатель "на любой класс, у которого есть такой-то метод (такие-то методы)"?
Не знаю. Подскажите.
Это не лабораторка :) Последнюю "лабу" я делал лет 40 назад :)
Это контроллер. Куча устройств 1-wire, RS485, плюс Bluetooth, Wi-Fi, GSM. Пользователь определяет, что делать, если датчик показывает "такую-то" температуру. То-ли включить / выключить что-то, то ли отправить СМС.
Тогда это действительно проблема с архитектурой программы. Тут не нужны указатели на "неведомые" классы. Имхо, конечно, я не настаиваю..
Не знаю. Подскажите.
Не ожидал. Вы так смело спорили о том, что такое ООП :-)
Вот пример, разбирайтесь
Либо ты делаешь базовый класс и вызываешь методы дочерних по желанию, но тут не дельфи, rtti даже близко не пахнет, либо, что проще на контроллерах, заводишь указатели на функции и назначаешь их обработчиками кнопок (их можно переопределять по желанию), а внутри вызывай методы какого хочешь класса. Так можно сделать "плавающие" кнопки, повесить на любую кнопку любой отклик "на лету".
Другими словами вы создаете указатель на базовый класс, а затем присваиваете ему адрес объекта производного класса ?
Другими словами вы создаете указатель на базовый класс, а затем присваиваете ему адрес объекта производного класса ?
Главное, чтобы в базовом классе были определены ВСЕ функции которые могут быть вызваны в дочерних. Пусть даже они будут pure virtual.
Ага. И созданный таким образом объект вполне законно является и объектом типа CGlobal, и объектом типа KakaFirst. Это и есть полиморфизм в данном случае.
Только помни, что по указателю на базовый класс нельзя вызвать функции дочерних, не описаных в базовом
Да, создавая дочерний класс с такими-же функциями, Вы переопределяете функции родительского класса. Это я уже пробовал, но в базовом классе нужно создать много "пустых" процедур и функций, т.к. его наследники СЛИШКОМ разные :(
Я думал о чем-то типа:
поздравляю. По ООП тебе твёрдая 2.
Да, создавая дочерний класс с такими-же функциями, Вы переопределяете функции родительского класса. Это я уже пробовал, но в базовом классе нужно создать много "пустых" процедур и функций, т.к. его наследники СЛИШКОМ разные :(
Вы мой пример видели? Что там по Вашему такое
Если думаете, что что бы место заполнить, то таки нет.
Вспоминаю #23 (и продолжение)- это правда Вы были? Или Ваш экаунт взломали?
С этим я пока не разобрался :(
Так Вы попробуйте переставить местами - сначала разбирайтесь, а потом посты пишите.
Если бы я сам во всем разобрался, я бы не спрашивал :)
А для чего я Вам пример писал? Уже начинаю жалеть потраченного времени :-(
то, что нужно, называется интерфейс, в #15 вам показал Евгений Петрович, как надо. Может, в современном си ещё более удобные способы есть, уж не глядел я.
А для чего я Вам пример писал? Уже начинаю жалеть потраченного времени :-(
Сорри, отвлекают постоянно :(
Если Вам угодно исполнять какие-то операции по хотелкам юзера, можно и без классов обойтись. Вот пример, запускайте, смотрите. Только сразу предупреждаю, что это
извращениеособенная ориентация.Если Вам угодно исполнять какие-то операции по хотелкам юзера, можно и без классов обойтись.
Я бы хотел этого избежать (хотелок юзера), но пока не знаю как :( Контроллер не имеет заранее известного количества устройств, хотя я УВЕРЕН, что на практике их будет не более трех-пяти, причем у всех одинаковый состав - датчики температуры (2...4), датчики рН (0..2), исполнительный блок (1).
А с чего вы вообще вообразили, что можете создать такой контроллер? С вашими-то нулевыми знаниями?
..... заводишь указатели на функции и назначаешь их обработчиками кнопок (их можно переопределять по желанию), а внутри вызывай методы какого хочешь класса. Так можно сделать "плавающие" кнопки, повесить на любую кнопку любой отклик "на лету".
У меня реализован такой метод для кнопок (поскольку их заранее известное количество), но там однотипные указатели: typedef void (*pFunc)();
При нажатии на кнопку (тачскрин) "открывается" определенное окно (или другие действия, для кнопок ручного управления).
Ну это не первый контроллер :) Но там программу писал не я.
https://reefcentral.ru/articles/151/6759/
Ну и такое еще:
https://reefcentral.ru/articles/151/7189/
Прочитай любое базовое введение в классы и зачем они нужны. Там всё есть.
Вот пример, разбирайтесь
Вот эту строку можете объяснить ?
void
whoAreYou(
void
) { method1(); method2(); }
Вот эту строку можете объяснить ?
void
whoAreYou(
void
) { method1(); method2(); }
Самая обыкновенная функция.
Может, так понятнее?
Хм ... это я перегрелся :) Я же сам так часто пишу, не построчно :) Сорри.
Остальное вроде понятно.
Хочу еще попробовать создать ОДИН класс для всего (собственно "все" это 5 классов), который состоит из указателей на другие классы. Что-то такое:
Тогда по идее к любому устройству можно будет обращаться через ALL.bt.read(); или там ALL.ow1[12].write();
Лучше не класс, а структуру :)
Лучше не класс, а структуру :)
1. В чём, по-Вашему, разница между классом и структурой?
2. Что было у меня в примере?
Тогда по идее к любому устройству можно будет обращаться через ALL.bt.read(); или там ALL.ow1[12].write();
Насчёт "по идее" не знаю, может и можно, а на практике - так обращаться нельзя :-(
Почему ? Такой метод работает хорошо, ну по крайней мере у меня работает хорошо, в ЧАСТНОМ проекте.
Если у меня есть класс, в котором много объектов, которые обращаются к функциям одного и того-же класса, то зачем мне все функции этого класса дублировать ? В своем классе я просто указываю ссылку на класс с процедурами / функциями.
Объектов класса cDS18B20 много, но они все "висят" в одной сети - OneWire и используют функции / процедуры класса сети.
Это плохо ? :(
Да,
Там еще один класс будет добавлен, сеть другого типа.
Немного не по теме ...
процедуры pinMode и digitalWrite не работают, т.е. ВООБЩЕ ничего не происходит. Пин так и остается INPUT.
Почему ? Такой метод работает хорошо, ну по крайней мере у меня работает хорошо, в ЧАСТНОМ проекте.
Т.е. Вы хотите сказать, что при описании
Вы в своём частном проекте используете конструкцию
и оно
работает хорошо
???
Боюсь, что Вы единственный, у кого это хорошо работает. У всех остальных такое просто не будет компилироваться :-(
Немного не по теме ...
процедуры pinMode и digitalWrite не работают, т.е. ВООБЩЕ ничего не происходит. Пин так и остается INPUT.
Привыкайте выкладывать скетч полностью. Я же Вам полностью выкладывал - бери и запускай. Так чего ж Вы мне огрызки суёте?
В этом кусочке я, например, вообще не вижу с чего бы ему работать. А додумывать за Вас что там ещё написано ... мало ли что я додумаю.
У тя область видимости класса XXX скорее всего, глобальная
Весь класс целиком. Рабочий.
Вы правы, ТАК не работает :(
Весь класс целиком. Рабочий.
Я уже перестал понимать к чему это. К #42 или к #44?
Но, в любом случае повторю второй раз (третий раз повторять не буду, просто буду игнорировать Ваши вопросы). Если Вы хотите задать вопрос, приводите скетч полностью, чтобы его можно было просто взять и запустить без дописывания и/или удаления чего-либо. Если будете приводить огрызки, ответов от меня больше не будет никаких.