Есть среда программирования, которая не в полной мере поддерживает ООП.
В ней можно создавать и наследовать классы, но нету возможности использовать виртуальную функцию.
Если в базовом классе вызвать виртуальную функцию, то даже если она переопределена в классе-наследние, все равно будет вызвана функция базового класса.
Чем можно заменить виртуальные функции в данном случае?
Виртуальные функции очень нужны.
Грубый пример. Есть базовый класс, который читает данные из БД.
Создается несколько наследников, которые переопределяют функцию чтения из БД.
Затем создаются несколько экземпляров этих наследников, указатели на них сохраняются в массиве.
Затем в цикле по массиву нужно вызвать функцию чтения.
Как это сделать без виртуальных функций?
Здравствуйте, zelenprog, Вы писали:
Z>Добрый день!
Z>Есть среда программирования, которая не в полной мере поддерживает ООП. Z>В ней можно создавать и наследовать классы, но нету возможности использовать виртуальную функцию. Z>Если в базовом классе вызвать виртуальную функцию, то даже если она переопределена в классе-наследние, все равно будет вызвана функция базового класса.
Z>Чем можно заменить виртуальные функции в данном случае? Z>Виртуальные функции очень нужны.
Z>Грубый пример. Есть базовый класс, который читает данные из БД. Z>Создается несколько наследников, которые переопределяют функцию чтения из БД. Z>Затем создаются несколько экземпляров этих наследников, указатели на них сохраняются в массиве. Z>Затем в цикле по массиву нужно вызвать функцию чтения. Z>Как это сделать без виртуальных функций?
Здравствуйте, zelenprog, Вы писали:
Z>Как это сделать без виртуальных функций?
Для виртуальных функций нужно чтобы в языке было что-то типа понятия "переменная типа функции" (переменной можно присвоить функцию)
В C/C++ это указатель на функцию, во всяких C# делегаты. Если такой концепции нет, то все, приплыли.
Здравствуйте, zelenprog, Вы писали:
Z>Как это сделать без виртуальных функций?
Так понимаю речь о полиморфизме. Я тут почитал комментарий выше, но некоторые языки даже указатель функции не умеют. В этом случае можно использовать оператор множественного выбора, который не нужно путать с условным оператором, там формируются разные конструкции на уровне кода. Но если и его нет, тогда есть ещё и условный оператор, хотя это похуже будет. Но существуют и другие виды полиморфизма, наоборот более продвинутые, думаю нужно просто выбрать какой использовать.
Для примера Qt генерит вот такой код из mainwindow.cpp в moc_mainwindow.cpp, а ведь это популярная система.
void MainWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
MainWindow *_t = static_cast<MainWindow *>(_o);
Q_UNUSED(_t)
switch (_id) {
case 0: _t->on_zoom_in_button_clicked(); break;
case 1: _t->on_zoom_out_button_clicked(); break;
default: ;
}
}
Q_UNUSED(_a);
}
Можно хранить ID(который уникален для всех классов) внутри базового класса. Потом по этому id выбирать и вызывать конкретную реализацию, например, простым switch'ом.
Сделать небольшой обработчик скриптов (их на гите миллион) и просто вызывать некую строчку, которая и будет скриптом. А строчку уже каждый дочерний класс по-своему переопределяет. Изврат, конечно, но какая ситуация такое и решение
K>Можно хранить ID(который уникален для всех классов) внутри базового класса. Потом по этому id выбирать и вызывать конкретную реализацию, например, простым switch'ом.
А как по ID найти реализацию?
Где то придется хранить массив созданных объектов-наследников. И искать по ID в этом массиве. Так?
Если виртуальных функций нет, значит они не нужны. Надо писать код так, как задумывалось создателями или менять язык. Изобрести указатель на функцию можно, но не нужно.
Здравствуйте, zelenprog, Вы писали:
Z>Шаблонов тоже нету.
Шаблоны это обобщённое программирование, а ветвление относится к структурному программированию. Полиморфизм можно обеспечить даже на самом простом языке. Выше я уже написал про оператор множественного выбора, в крайнем случае условный оператор.
У меня есть статья Почему программисты прошлого были умнее. Вот ты похоже знаком с высокоуровневыми абстракциями, со всякими таблицами виртуальных методов хотя бы на уровне пользователя. А что можно вызывать одно или другое в зависимости от числа как в операторе множественного выбора или условия как в условном операторе не задумываешься.
Ещё раз вот это оператор множественного выбора.
switch (_id) {
case 0: _t->on_zoom_in_button_clicked(); break;
case 1: _t->on_zoom_out_button_clicked(); break;
default: ;
}
Как видишь здесь нет никаких шаблонов. Условный оператор это if, elseif, else. Чтобы понять различие нужно понять, что он генерирует хотя бы в ассемблере.
В целом же тебе надо разобраться какие конструкции языка у тебя есть, тогда будет понятно, какой вид полиморфного поведения тебе доступен и там уже выбрать архитектуру программы.
Здравствуйте, zelenprog, Вы писали:
Z>Про switch я конечно же знаю. Z>Не понятно откуда базовый класс возьмет ссылки на наследников, чтобы выбрать из них нужного. Z>Вот в чем проблема.
В моём понимании есть.
1. Инструкции — конструкции языка программирования встроенные в компилятор.
2. Архитектура — конструкции составленные из инструкций по определённым самими программистами правилам.
Если у тебя нет переопределения методов, то есть и другие варианты, но это другие виды архитектур. Количество архитектур зависит от количества инструкций, но готовые решения задач которые нужно с помощью них решить взаимозаменяемы.
Мне кажется тема уже почти исчерпана, если только кто-то за тебя не напишет архитектуру программы решающую твою задачу.
class Base {
static constexpr int ID = 1;
Base(int id) : id_(id) {}
int ReadBd() {
switch(id_) {
case Base::ID:
return 11;
case Foo::ID:
return ((Foo*)this)->ReadBd();
}
unreachable();
}
};
class Foo : Base {
static constexpr int ID = 2;
Foo() : Base(ID) {}
int ReadBd() { return 22; }
};
Здравствуйте, koenjihyakkei, Вы писали:
K>Упрощенно на условных плюсах как то так: K>
K> return ((Foo*)this)->ReadBd();
K>};
K>
Здесь предполагается что существует кастинг к базовому классу. Вангую — его тоже нет
В общем я думаю пора колоться, что за язык-то? Что там вообще есть?