Ну наверное проще создать класс который и будет реализовывать эти функции в зависимости от типа объекта.
Через перегрузку методов.
Суть в том, что этот класс будет знать о всех наследниках.
Можно приводить к типу и вызывать метод типа
и солнце б утром не вставало, когда бы не было меня
Да, абстрактных классов и интерфейсов нету.
Но без них можно обойтись, так как строгой типизации нету. Это скриптовый язык.
Будет просто переменная, в которой хранится ссылка (указатель) на объект типа "базовый".
Точнее, эта "переменная" — это this. То есть в методе базового класса через this вызывается виртуальная функция. Нужно чтобы произошел вызов "реальной" переопределенной в потомке функции.
А делегат — это же просто шаблон проектирования. Делегат наверно в моей среде можно сделать.
Здравствуйте, zelenprog, Вы писали:
Z>Да, абстрактных классов и интерфейсов нету. Z>Но без них можно обойтись, так как строгой типизации нету. Это скриптовый язык. Z>Будет просто переменная, в которой хранится ссылка (указатель) на конечный объект.
Z>А делегат — это же просто шаблон проектирования. Делегат наверно в моей среде можно сделать.
Под "делегатом" я имел в виду указатель на функцию, они так во многих языках называются.
Для скриптового языка, если нет делегатов (возможности вызвать функцию через переменную, как ниже например), IMHO — никак.
function foo() {}
function bar() {}
var x;
x = foo;
x()
x = bar;
x()
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, то всегда получается ссылка на сам объект базового класса.
В этом причина того, что виртуальные функции не работают.
S>Ну наверное проще создать класс который и будет реализовывать эти функции в зависимости от типа объекта. S> Через перегрузку методов. S> Суть в том, что этот класс будет знать о всех наследниках. S> Можно приводить к типу и вызывать метод типа
Не совсем понял.
Этот класс будет хранить ссылки на все объекты в цепочке наследования?
Тогда базовый класс должен иметь доступ к объекту этого класса. Как это сделать?
Не получится ли "зацикливания" ссылок друг на друга?
Здравствуйте, zelenprog, Вы писали:
bnk>>В общем я думаю пора колоться, что за язык-то? Что там вообще есть?
Z>Если я скажу — засмеёте.
Если это скрипт, возможно есть функция типа "EVAL", которая позволяет создать и выполнить произвольный кусок текста в рантайме.
Тогда имя функции можно подставить в виде строки.
bnk>Если это скрипт, возможно есть функция типа "EVAL", которая позволяет создать и выполнить произвольный кусок текста в рантайме. bnk>Тогда имя функции можно подставить в виде строки.
Да, скриптовый язык.
Есть похожая команда, которая выполняет произвольный код в виде текста.
Но я не могу понять, какой код надо выполнить?
Суть в том, чтобы находясь в базовом классе каким-то образом получить ссылку на объект-наследник.
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 + "()")
}
Если и конструкторов тоже нет, можно при инициализации объекта поле задать.
Здравствуйте, zelenprog, Вы писали:
Z>Но вот этого преобразования нету на "моем" языке: "(Foo*)this". Z>Если в функции базового класса обратиться к this, то всегда получается ссылка на сам объект базового класса.
Так, может, тогда все-таки стоит раскрыть что за язык используется?
А то возможно там вообще нет никакой возможности вызвать функцию производного класса, имея указатель на базовый.
Тогда никакого полиморфизма в принципе не получится.
S>>Ну наверное проще создать класс который и будет реализовывать эти функции в зависимости от типа объекта. S>> Через перегрузку методов. S>> Суть в том, что этот класс будет знать о всех наследниках. S>> Можно приводить к типу и вызывать метод типа
Z>Не совсем понял. Z>Этот класс будет хранить ссылки на все объекты в цепочке наследования? Z>Тогда базовый класс должен иметь доступ к объекту этого класса. Как это сделать? Z>Не получится ли "зацикливания" ссылок друг на друга?
Нет он просто будет вызывать методы соответствующего класса.
Или может сам реализовать методы для каждого типа.
А вот базовый класс будет его вызывать метод этого класса передавая this и параметры. А внутри этот класс будет знать, что за тип его вызывает и вызывать соответствующие методы.
и солнце б утром не вставало, когда бы не было меня
В принципе такое прокатит. Но это если вызывать виртуальную функцию извне.
А если нужно вызвать виртуальную функцию из метода базового класса?
Вряд ли в базовом методе this сможет "связаться" с "child_foo()".
Надо попробовать.
Здравствуйте, zelenprog, Вы писали:
bnk>>function bar(Base x) { bnk>> EVAL("x." + x.func_name + "()") bnk>>} bnk>>[/code]
Z>В принципе такое прокатит. Но это если вызывать виртуальную функцию извне. Z>А если нужно вызвать виртуальную функцию из метода базового класса? Z>Вряд ли в базовом методе this сможет "связаться" с "child_foo()". Z>Надо попробовать.
Только не забывай, что eval это всегда тормоза и проблемы с безопасностью.
Здравствуйте, zelenprog, Вы писали:
Z>Есть среда программирования, которая не в полной мере поддерживает ООП.
А что это за среда/язык?
Так можно много чего насоветовать.
Здравствуйте, zelenprog, Вы писали:
Z>Добрый день!
Z>Есть среда программирования, которая не в полной мере поддерживает ООП. Z>В ней можно создавать и наследовать классы, но нету возможности использовать виртуальную функцию. Z>Если в базовом классе вызвать виртуальную функцию, то даже если она переопределена в классе-наследние, все равно будет вызвана функция базового класса.
Z>Чем можно заменить виртуальные функции в данном случае? Z>Виртуальные функции очень нужны.
Z>Грубый пример. Есть базовый класс, который читает данные из БД. Z>Создается несколько наследников, которые переопределяют функцию чтения из БД. Z>Затем создаются несколько экземпляров этих наследников, указатели на них сохраняются в массиве. Z>Затем в цикле по массиву нужно вызвать функцию чтения. Z>Как это сделать без виртуальных функций?
Если это скриптовый язык с динамической типизацией, который позволяет в массив складывать объекты разных типов
то
Попробуйте обойтись без наследования вовсе. Просто отдельные классы, в которых есть метод с одинаковым именем и набором параметров.
Обычные не виртуальные методы.
S>Если это скриптовый язык с динамической типизацией, который позволяет в массив складывать объекты разных типов
Да, в массив можно сложить объекты любых типов.
S>Попробуйте обойтись без наследования вовсе. Просто отдельные классы, в которых есть метод с одинаковым именем и набором параметров. S>Обычные не виртуальные методы.
А как потом этим пользоваться?
У меня задача — из метода базового класса сделать вызов другого метода, который может быть переопределен у потомка.
Я прочитал в интернете, что чисто с архитектурной точки зрения, наследование — это не очень хорошо, так как наследование является сильным связыванием.
Мой скриптовый язык позволяет наследовать классы.
Но как заменить обычные виртуальные функции, другими архитектурными решениями?
S>Кстати, есть ли там статические методы?
Нет, статических методов и статических свойств нету.
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) в метод реализации в качестве параметра.