Чем заменить виртуальные функции?
От: zelenprog  
Дата: 14.07.23 13:06
Оценка:
Добрый день!

Есть среда программирования, которая не в полной мере поддерживает ООП.
В ней можно создавать и наследовать классы, но нету возможности использовать виртуальную функцию.
Если в базовом классе вызвать виртуальную функцию, то даже если она переопределена в классе-наследние, все равно будет вызвана функция базового класса.

Чем можно заменить виртуальные функции в данном случае?
Виртуальные функции очень нужны.

Грубый пример. Есть базовый класс, который читает данные из БД.
Создается несколько наследников, которые переопределяют функцию чтения из БД.
Затем создаются несколько экземпляров этих наследников, указатели на них сохраняются в массиве.
Затем в цикле по массиву нужно вызвать функцию чтения.
Как это сделать без виртуальных функций?
Re: Чем заменить виртуальные функции?
От: Stanislav V. Zudin Россия  
Дата: 14.07.23 13:15
Оценка: 1 (1) +2
Здравствуйте, zelenprog, Вы писали:

Z>Чем можно заменить виртуальные функции в данном случае?

Z>Виртуальные функции очень нужны.

Использовать суррогат, как в Си — указатели на функции.
_____________________
С уважением,
Stanislav V. Zudin
Re[2]: Чем заменить виртуальные функции?
От: zelenprog  
Дата: 14.07.23 13:27
Оценка:
SVZ>Использовать суррогат, как в Си — указатели на функции.

Нету указателей на функции.
Есть только указатели (ссылки) на объекты.
Re[3]: Чем заменить виртуальные функции?
От: Stanislav V. Zudin Россия  
Дата: 14.07.23 13:31
Оценка: +1
Здравствуйте, zelenprog, Вы писали:


SVZ>>Использовать суррогат, как в Си — указатели на функции.


Z>Нету указателей на функции.

Z>Есть только указатели (ссылки) на объекты.

А что ещё есть?
Интерфейсы есть?
Индексы? Можно функции собрать в таблицу и дёргать по индексу?
Функторы использовать можно?
_____________________
С уважением,
Stanislav V. Zudin
Re: Чем заменить виртуальные функции?
От: Nonmanual Worker  
Дата: 14.07.23 13:36
Оценка:
Здравствуйте, zelenprog, Вы писали:

Z>Добрый день!


Z>Есть среда программирования, которая не в полной мере поддерживает ООП.

Z>В ней можно создавать и наследовать классы, но нету возможности использовать виртуальную функцию.
Z>Если в базовом классе вызвать виртуальную функцию, то даже если она переопределена в классе-наследние, все равно будет вызвана функция базового класса.

Z>Чем можно заменить виртуальные функции в данном случае?

Z>Виртуальные функции очень нужны.

Z>Грубый пример. Есть базовый класс, который читает данные из БД.

Z>Создается несколько наследников, которые переопределяют функцию чтения из БД.
Z>Затем создаются несколько экземпляров этих наследников, указатели на них сохраняются в массиве.
Z>Затем в цикле по массиву нужно вызвать функцию чтения.
Z>Как это сделать без виртуальных функций?

Использовать композицию.
Re: Чем заменить виртуальные функции?
От: bnk СССР http://unmanagedvisio.com/
Дата: 14.07.23 13:40
Оценка: +2
Здравствуйте, zelenprog, Вы писали:

Z>Как это сделать без виртуальных функций?


Для виртуальных функций нужно чтобы в языке было что-то типа понятия "переменная типа функции" (переменной можно присвоить функцию)
В C/C++ это указатель на функцию, во всяких C# делегаты. Если такой концепции нет, то все, приплыли.
Re: Чем заменить виртуальные функции?
От: velkin Удмуртия https://kisa.biz
Дата: 14.07.23 13:42
Оценка:
Здравствуйте, 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);
}
Re[2]: Чем заменить виртуальные функции?
От: zelenprog  
Дата: 14.07.23 13:44
Оценка:
NW>Использовать композицию.

Можно поподробнее?
Re[2]: Чем заменить виртуальные функции?
От: zelenprog  
Дата: 14.07.23 13:46
Оценка:
V>Для примера Qt генерит вот такой код из mainwindow.cpp в moc_mainwindow.cpp, а ведь это популярная система.
V>
V>void MainWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
V>{
V>    if (_c == QMetaObject::InvokeMetaMethod) {
V>        MainWindow *_t = static_cast<MainWindow *>(_o);
V>        Q_UNUSED(_t)
V>        switch (_id) {
V>        case 0: _t->on_zoom_in_button_clicked(); break;
V>        case 1: _t->on_zoom_out_button_clicked(); break;
V>        default: ;
V>        }
V>    }
V>    Q_UNUSED(_a);
V>}
V>


Шаблонов тоже нету.
Re: Чем заменить виртуальные функции?
От: koenjihyakkei Россия  
Дата: 14.07.23 13:47
Оценка:
Здравствуйте, zelenprog, Вы писали:

Можно хранить ID(который уникален для всех классов) внутри базового класса. Потом по этому id выбирать и вызывать конкретную реализацию, например, простым switch'ом.
Re: Чем заменить виртуальные функции?
От: Нomunculus Россия  
Дата: 14.07.23 13:50
Оценка:
Здравствуйте, zelenprog, Вы писали:

Сделать небольшой обработчик скриптов (их на гите миллион) и просто вызывать некую строчку, которая и будет скриптом. А строчку уже каждый дочерний класс по-своему переопределяет. Изврат, конечно, но какая ситуация такое и решение
Re[2]: Чем заменить виртуальные функции?
От: zelenprog  
Дата: 14.07.23 14:03
Оценка:
K>Можно хранить ID(который уникален для всех классов) внутри базового класса. Потом по этому id выбирать и вызывать конкретную реализацию, например, простым switch'ом.

А как по ID найти реализацию?
Где то придется хранить массив созданных объектов-наследников. И искать по ID в этом массиве. Так?
Re: Чем заменить виртуальные функции?
От: vsb Казахстан  
Дата: 14.07.23 14:05
Оценка: +2
Если виртуальных функций нет, значит они не нужны. Надо писать код так, как задумывалось создателями или менять язык. Изобрести указатель на функцию можно, но не нужно.
Re[4]: Чем заменить виртуальные функции?
От: zelenprog  
Дата: 14.07.23 14:05
Оценка:
SVZ>А что ещё есть?
SVZ>Интерфейсы есть?

Нету.

SVZ>Индексы? Можно функции собрать в таблицу и дёргать по индексу?


Нет. Раз нету указателей на функции, значит их и собрать в таблицу нельзя.

SVZ>Функторы использовать можно?


А это как?
Re[3]: Чем заменить виртуальные функции?
От: velkin Удмуртия https://kisa.biz
Дата: 14.07.23 14:09
Оценка:
Здравствуйте, 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. Чтобы понять различие нужно понять, что он генерирует хотя бы в ассемблере.

В целом же тебе надо разобраться какие конструкции языка у тебя есть, тогда будет понятно, какой вид полиморфного поведения тебе доступен и там уже выбрать архитектуру программы.
Re[5]: Чем заменить виртуальные функции?
От: Stanislav V. Zudin Россия  
Дата: 14.07.23 14:15
Оценка:
Здравствуйте, zelenprog, Вы писали:

SVZ>>Функторы использовать можно?


Z>А это как?


если по С++-ному, то класс с оператором().
Но без интерфейса тоже никак.

Запустить другой процесс можно?
_____________________
С уважением,
Stanislav V. Zudin
Re[4]: Чем заменить виртуальные функции?
От: zelenprog  
Дата: 14.07.23 14:20
Оценка:
Про switch я конечно же знаю.

Не понятно откуда базовый класс возьмет ссылки на наследников, чтобы выбрать из них нужного.
Вот в чем проблема.
Re[5]: Чем заменить виртуальные функции?
От: velkin Удмуртия https://kisa.biz
Дата: 14.07.23 14:36
Оценка:
Здравствуйте, zelenprog, Вы писали:

Z>Про switch я конечно же знаю.

Z>Не понятно откуда базовый класс возьмет ссылки на наследников, чтобы выбрать из них нужного.
Z>Вот в чем проблема.

Это потому что при переопределении методов за тебя всё делала таблица виртуальных методов.

В моём понимании есть.
1. Инструкции — конструкции языка программирования встроенные в компилятор.
2. Архитектура — конструкции составленные из инструкций по определённым самими программистами правилам.

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

Мне кажется тема уже почти исчерпана, если только кто-то за тебя не напишет архитектуру программы решающую твою задачу.
Re[3]: Чем заменить виртуальные функции?
От: koenjihyakkei Россия  
Дата: 14.07.23 14:38
Оценка:
Здравствуйте, zelenprog, Вы писали:

Упрощенно на условных плюсах как то так:
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; }
};
Re[4]: Чем заменить виртуальные функции?
От: bnk СССР http://unmanagedvisio.com/
Дата: 14.07.23 14:51
Оценка:
Здравствуйте, koenjihyakkei, Вы писали:

K>Упрощенно на условных плюсах как то так:

K>
K>           return ((Foo*)this)->ReadBd();
K>};

K>


Здесь предполагается что существует кастинг к базовому классу. Вангую — его тоже нет
В общем я думаю пора колоться, что за язык-то? Что там вообще есть?
Отредактировано 14.07.2023 14:55 bnk . Предыдущая версия . Еще …
Отредактировано 14.07.2023 14:53 bnk . Предыдущая версия .
Отредактировано 14.07.2023 14:53 bnk . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.