Чем заменить виртуальные функции?
От: 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 . Предыдущая версия .
Re: Чем заменить виртуальные функции?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 14.07.23 15:13
Оценка:
Здравствуйте, zelenprog, Вы писали:

Ну наверное проще создать класс который и будет реализовывать эти функции в зависимости от типа объекта.
Через перегрузку методов.
Суть в том, что этот класс будет знать о всех наследниках.
Можно приводить к типу и вызывать метод типа
и солнце б утром не вставало, когда бы не было меня
Re[3]: Чем заменить виртуальные функции?
От: Gurney Великобритания www.kharlamov.biz
Дата: 14.07.23 15:18
Оценка:
Здравствуйте, zelenprog, Вы писали:


NW>>Использовать композицию.


Z>Можно поподробнее?


https://www.wikiwand.com/en/Composition_over_inheritance
Re[4]: Чем заменить виртуальные функции?
От: bnk СССР http://unmanagedvisio.com/
Дата: 14.07.23 15:46
Оценка:
Здравствуйте, Gurney, Вы писали:

NW>>>Использовать композицию.


Z>>Можно поподробнее?


G>https://www.wikiwand.com/en/Composition_over_inheritance


А можно еще чуть подробнее (с учетом, что абстрактных классов, делегатов и интерфейсов, тоже, видимо, нет)?
Re[4]: Чем заменить виртуальные функции?
От: zelenprog  
Дата: 14.07.23 16:29
Оценка:
G>https://www.wikiwand.com/en/Composition_over_inheritance

Спасибо. Идею понял.
С первого взгляда кажется, что такой подход поможет решить мою проблему.
Re[5]: Чем заменить виртуальные функции?
От: zelenprog  
Дата: 14.07.23 16:32
Оценка:
G>>https://www.wikiwand.com/en/Composition_over_inheritance

bnk>А можно еще чуть подробнее (с учетом, что абстрактных классов, делегатов и интерфейсов, тоже, видимо, нет)?


Да, абстрактных классов и интерфейсов нету.
Но без них можно обойтись, так как строгой типизации нету. Это скриптовый язык.
Будет просто переменная, в которой хранится ссылка (указатель) на объект типа "базовый".
Точнее, эта "переменная" — это this. То есть в методе базового класса через this вызывается виртуальная функция. Нужно чтобы произошел вызов "реальной" переопределенной в потомке функции.

А делегат — это же просто шаблон проектирования. Делегат наверно в моей среде можно сделать.
Отредактировано 17.07.2023 5:34 zelenprog . Предыдущая версия .
Re[5]: Чем заменить виртуальные функции?
От: zelenprog  
Дата: 14.07.23 16:54
Оценка:
bnk>В общем я думаю пора колоться, что за язык-то? Что там вообще есть?

Если я скажу — засмеёте.
Пока промолчу.
Re[6]: Чем заменить виртуальные функции?
От: bnk СССР http://unmanagedvisio.com/
Дата: 14.07.23 16:55
Оценка:
Здравствуйте, zelenprog, Вы писали:

Z>Да, абстрактных классов и интерфейсов нету.

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

Z>А делегат — это же просто шаблон проектирования. Делегат наверно в моей среде можно сделать.


Под "делегатом" я имел в виду указатель на функцию, они так во многих языках называются.
Для скриптового языка, если нет делегатов (возможности вызвать функцию через переменную, как ниже например), IMHO — никак.


function foo() {}

function bar() {}

var x;

x = foo;
x()

x = bar;
x()
Re[4]: Чем заменить виртуальные функции?
От: zelenprog  
Дата: 14.07.23 16:57
Оценка:
K>Упрощенно на условных плюсах как то так:
K>
K>class Base {
K>    static constexpr int ID = 1;
K>    Base(int id) : id_(id) {}

K>    int ReadBd() {
K>        switch(id_) {
K>        case Base::ID:
K>           return 11;
K>        case Foo::ID:
K>           return ((Foo*)this)->ReadBd();
K>        }
K>        unreachable();
K>    }
K>};

K>class Foo : Base {
K>    static constexpr int ID = 2;
K>    Foo() : Base(ID) {}

K>    int ReadBd() { return 22; }
K>};

K>


Спасибо за идею.
Но вот этого преобразования нету на "моем" языке: "(Foo*)this".
Если в функции базового класса обратиться к this, то всегда получается ссылка на сам объект базового класса.
В этом причина того, что виртуальные функции не работают.
Re[2]: Чем заменить виртуальные функции?
От: zelenprog  
Дата: 14.07.23 17:05
Оценка:
S>Ну наверное проще создать класс который и будет реализовывать эти функции в зависимости от типа объекта.
S> Через перегрузку методов.
S> Суть в том, что этот класс будет знать о всех наследниках.
S> Можно приводить к типу и вызывать метод типа

Не совсем понял.
Этот класс будет хранить ссылки на все объекты в цепочке наследования?
Тогда базовый класс должен иметь доступ к объекту этого класса. Как это сделать?
Не получится ли "зацикливания" ссылок друг на друга?
Re[6]: Чем заменить виртуальные функции?
От: bnk СССР http://unmanagedvisio.com/
Дата: 14.07.23 17:07
Оценка:
Здравствуйте, zelenprog, Вы писали:

bnk>>В общем я думаю пора колоться, что за язык-то? Что там вообще есть?


Z>Если я скажу — засмеёте.


Если это скрипт, возможно есть функция типа "EVAL", которая позволяет создать и выполнить произвольный кусок текста в рантайме.
Тогда имя функции можно подставить в виде строки.
Re[7]: Чем заменить виртуальные функции?
От: zelenprog  
Дата: 14.07.23 17:15
Оценка:
bnk>Если это скрипт, возможно есть функция типа "EVAL", которая позволяет создать и выполнить произвольный кусок текста в рантайме.
bnk>Тогда имя функции можно подставить в виде строки.

Да, скриптовый язык.
Есть похожая команда, которая выполняет произвольный код в виде текста.

Но я не могу понять, какой код надо выполнить?
Суть в том, чтобы находясь в базовом классе каким-то образом получить ссылку на объект-наследник.
Re[8]: Чем заменить виртуальные функции?
От: bnk СССР http://unmanagedvisio.com/
Дата: 14.07.23 17:31
Оценка:
Здравствуйте, zelenprog, Вы писали:


bnk>>Если это скрипт, возможно есть функция типа "EVAL", которая позволяет создать и выполнить произвольный кусок текста в рантайме.

bnk>>Тогда имя функции можно подставить в виде строки.

Z>Да, скриптовый язык.

Z>Есть похожая команда, которая выполняет произвольный код в виде текста.

Z>Но я не могу понять, какой код надо выполнить?

Z>Суть в том, чтобы находясь в базовом классе каким-то образом получить ссылку на объект-наследник.

Ну я имел в виду что-то такое не прокатит:

class Base {
  string func_name;

  Base() { func_name = "base_foo" }
  function base_foo() {}
}

class Child extends Base {
  Child() { func_name = "child_foo" }
  function child_foo() {}
}

function bar(Base x) {
  EVAL("x." + x.func_name + "()")
}


Если и конструкторов тоже нет, можно при инициализации объекта поле задать.
Отредактировано 14.07.2023 17:52 bnk . Предыдущая версия .
Re[5]: Чем заменить виртуальные функции?
От: koenjihyakkei Россия  
Дата: 14.07.23 17:44
Оценка:
Здравствуйте, zelenprog, Вы писали:

Z>Но вот этого преобразования нету на "моем" языке: "(Foo*)this".

Z>Если в функции базового класса обратиться к this, то всегда получается ссылка на сам объект базового класса.

Так, может, тогда все-таки стоит раскрыть что за язык используется?
А то возможно там вообще нет никакой возможности вызвать функцию производного класса, имея указатель на базовый.
Тогда никакого полиморфизма в принципе не получится.
Re[3]: Чем заменить виртуальные функции?
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 14.07.23 18:51
Оценка:
Здравствуйте, zelenprog, Вы писали:


S>>Ну наверное проще создать класс который и будет реализовывать эти функции в зависимости от типа объекта.

S>> Через перегрузку методов.
S>> Суть в том, что этот класс будет знать о всех наследниках.
S>> Можно приводить к типу и вызывать метод типа

Z>Не совсем понял.

Z>Этот класс будет хранить ссылки на все объекты в цепочке наследования?
Z>Тогда базовый класс должен иметь доступ к объекту этого класса. Как это сделать?
Z>Не получится ли "зацикливания" ссылок друг на друга?

Нет он просто будет вызывать методы соответствующего класса.
Или может сам реализовать методы для каждого типа.
А вот базовый класс будет его вызывать метод этого класса передавая this и параметры. А внутри этот класс будет знать, что за тип его вызывает и вызывать соответствующие методы.
и солнце б утром не вставало, когда бы не было меня
Re[9]: Чем заменить виртуальные функции?
От: zelenprog  
Дата: 17.07.23 05:39
Оценка:
bnk>Ну я имел в виду что-то такое не прокатит:

bnk>
bnk>class Base {
bnk>  string func_name;

bnk>  Base() { func_name = "base_foo" }
bnk>  function base_foo() {}
bnk>}

bnk>class Child extends Base {
bnk>  Child() { func_name = "child_foo" }
bnk>  function child_foo() {}
bnk>}

bnk>function bar(Base x) {
bnk>  EVAL("x." + x.func_name + "()")
bnk>}
bnk>



В принципе такое прокатит. Но это если вызывать виртуальную функцию извне.
А если нужно вызвать виртуальную функцию из метода базового класса?
Вряд ли в базовом методе this сможет "связаться" с "child_foo()".
Надо попробовать.
Re[10]: Чем заменить виртуальные функции?
От: amironov79  
Дата: 17.07.23 07:07
Оценка:
Здравствуйте, zelenprog, Вы писали:

bnk>>function bar(Base x) {

bnk>> EVAL("x." + x.func_name + "()")
bnk>>}
bnk>>[/code]

Z>В принципе такое прокатит. Но это если вызывать виртуальную функцию извне.

Z>А если нужно вызвать виртуальную функцию из метода базового класса?
Z>Вряд ли в базовом методе this сможет "связаться" с "child_foo()".
Z>Надо попробовать.

Только не забывай, что eval это всегда тормоза и проблемы с безопасностью.
Re: Чем заменить виртуальные функции?
От: MaximVK Россия  
Дата: 21.07.23 09:26
Оценка: +1
Здравствуйте, zelenprog, Вы писали:

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

А что это за среда/язык?
Так можно много чего насоветовать.
Re: Чем заменить виртуальные функции?
От: Sm0ke Россия ksi
Дата: 08.08.23 18:32
Оценка:
Здравствуйте, zelenprog, Вы писали:

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


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

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

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

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

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

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

Если это скриптовый язык с динамической типизацией, который позволяет в массив складывать объекты разных типов
то
Попробуйте обойтись без наследования вовсе. Просто отдельные классы, в которых есть метод с одинаковым именем и набором параметров.
Обычные не виртуальные методы.

Кстати, есть ли там статические методы?
Re[2]: Чем заменить виртуальные функции?
От: zelenprog  
Дата: 10.08.23 05:55
Оценка: 7 (1)
S>Если это скриптовый язык с динамической типизацией, который позволяет в массив складывать объекты разных типов

Да, в массив можно сложить объекты любых типов.

S>Попробуйте обойтись без наследования вовсе. Просто отдельные классы, в которых есть метод с одинаковым именем и набором параметров.

S>Обычные не виртуальные методы.

А как потом этим пользоваться?
У меня задача — из метода базового класса сделать вызов другого метода, который может быть переопределен у потомка.

Я прочитал в интернете, что чисто с архитектурной точки зрения, наследование — это не очень хорошо, так как наследование является сильным связыванием.
Мой скриптовый язык позволяет наследовать классы.
Но как заменить обычные виртуальные функции, другими архитектурными решениями?

S>Кстати, есть ли там статические методы?


Нет, статических методов и статических свойств нету.
Re[3]: Чем заменить виртуальные функции?
От: Sm0ke Россия ksi
Дата: 10.08.23 18:33
Оценка:
Здравствуйте, zelenprog, Вы писали:


S>>Если это скриптовый язык с динамической типизацией, который позволяет в массив складывать объекты разных типов


Z>Да, в массив можно сложить объекты любых типов.


Этот язык позволяет пройтись по такому массиву и вызвать для каждого элемента одноимённые методы?

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


Z>Я прочитал в интернете, что чисто с архитектурной точки зрения, наследование — это не очень хорошо, так как наследование является сильным связыванием.

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

Есть такая идиома pimpl
Вы можете сделать внешний класс (обёртка), который хранит в своём свойстве экземпляр другого класса (реализация).
Делаете разные классы реализаций, которые друг с другом не связаны. Но чтобы они все имели схожие наборы методов.

Из метода обёртки можно будет вызывать методы реализаций.

class base_1
{
  connect() {}
  close() {}
}

class base_2
{
  connect() {}
  close() {}
}

class wrap
{
  var impl

  do_something()
  {
    impl.connect()
    impl.close()
  }
}

var items = array( new wrap(new base_1), new wrap(new base_2) )
items each it { it.do_something() }


По сути это обычная инкапсуляция. Зато не требует наследования.
Но если у вас уже чётко прописана иерархия классов, на которую вы повлиять не можете — то думаю это вам не поможет)

Кстати если из метода класса реализации нужен метод внешней обёртки, то можно попробовать передать обёртку (this) в метод реализации в качестве параметра.
Отредактировано 10.08.2023 18:41 Sm0ke . Предыдущая версия .
Re[4]: Чем заменить виртуальные функции?
От: zelenprog  
Дата: 24.08.23 06:12
Оценка: 6 (1)
S>>>Если это скриптовый язык с динамической типизацией, который позволяет в массив складывать объекты разных типов

Z>>Да, в массив можно сложить объекты любых типов.


S>Этот язык позволяет пройтись по такому массиву и вызвать для каждого элемента одноимённые методы?


Да, это возможно.
По массиву можно прийтись и вызвать одинаковый метод для разных объектов, даже если это объекты разного типа (разных классов).

S>Есть такая идиома pimpl

S>Вы можете сделать внешний класс (обёртка), который хранит в своём свойстве экземпляр другого класса (реализация).
S>Делаете разные классы реализаций, которые друг с другом не связаны. Но чтобы они все имели схожие наборы методов.
S>Из метода обёртки можно будет вызывать методы реализаций.
S>По сути это обычная инкапсуляция. Зато не требует наследования.

Спасибо, идею понял. Попробую.

S>Но если у вас уже чётко прописана иерархия классов, на которую вы повлиять не можете — то думаю это вам не поможет)


Иерархия классов — это моя разработка. Я сам создавал все классы, начиная от базового.
В базовом(-ых) классе(-ах) задан некий универсальный алгоритм, который вызывает абстрактные (виртуальные) функции.
Эти "абстрактные" функции должны быть реализованы реальными виртуальными функциями в классах-наследниках. На C#, например, никакой проблемы с этим не было.
А вот на моем "новом" скриптовом языке я столкнулся с тем, что это невозможно сделать.

S>Кстати если из метода класса реализации нужен метод внешней обёртки, то можно попробовать передать обёртку (this) в метод реализации в качестве параметра.


Ага.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.