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 . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.