Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Синтаксис
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 27.01.2012, 03:33
shhmn shhmn вне форума
Прохожий
 
Регистрация: 27.01.2012
Сообщения: 6
Репутация: 10
По умолчанию функция возвращает функцию

Можно ли создать функцию, которая будет возвращать функцию?

Например:

Код:
type
   TFunc = function(x:real):real;

function mult(a:real):TFunc;
begin

 function res(x:real):real;
 begin
   res:=a*x;
 end;

 result:=res; 

end;
В общих чертах хотелось бы такое. Чтобы функция mult создавала в памяти объект функцию с нужным кодом и возвращала на неё указатель.

Такой механизм нетрудно реализовать с помощью объектов как таковых: описать класс с полем a и функцией res и создать экземпляр объект этого класса, инициировав нужным значением переменную a и потом передавая метод res куда нужно.

Важно на выходе иметь именно TFunc - функцию с одним аргументом, потому что она потом будет передаваться в др. функцию как переменная именно типа TFunc. Это к тому что function res(a,x:real):real, которая вроде как решает проблему, здесь не подходит.

На этом простом примере попытался объяснить, что мне нужно ) ,а именно функция (или процедура) от параметра, возвращающая функцию в которой этот параметр зашит.

Но может в Delphi есть возможность сделать это без объектов?

Последний раз редактировалось shhmn, 27.01.2012 в 05:06.
Ответить с цитированием
  #2  
Старый 27.01.2012, 04:35
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,029
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

попробуй вот так:

Код:
type
  TFunc = function (X: Real) : Read;

function F1(X : Real) : Real;
begin
...
end;

function F2(X : Real) : Real;
begin
...
end;

function GetFunc(Num : Integer) : TFunc;
begin
  Case Num Of
    1 : Result := @F1;
    2 : Result := @F2;
  End;
end;
Ответить с цитированием
  #3  
Старый 27.01.2012, 04:45
shhmn shhmn вне форума
Прохожий
 
Регистрация: 27.01.2012
Сообщения: 6
Репутация: 10
По умолчанию

Tолько у меня а вещественное, а здесь Num целое (к тому же много функций Fi (i=1,...,100 например) тяжеловато сделать)).

Тем не менее спасибо - как пример функции, возвращающей функцию, наверное хороший. Только хотелось бы понять границы синтаксиса, т.е. возможно ли реализовать с вещественным a и без объектов.

Также хотелось бы без глобальных переменных ) (не знаю, будет ли работать следующий код?))

Код:
var a:real;

type
  TFunc = function (x:real):reaL;

function res(x:real):real;
begin
  result:=a*x;
end;

function mult(b:real):TFunc;
begin 
  a:=b;
  Result:=res;
end;

Последний раз редактировалось shhmn, 27.01.2012 в 05:18.
Ответить с цитированием
  #4  
Старый 27.01.2012, 06:56
Pyro Pyro вне форума
Так проходящий
 
Регистрация: 18.07.2011
Сообщения: 805
Версия Delphi: 7Lite
Репутация: 6063
По умолчанию

Цитата:
Важно на выходе иметь именно TFunc
а если объект с функцией типа TFunc ?
Ответить с цитированием
  #5  
Старый 27.01.2012, 07:20
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,029
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Здесь Num - просто некоторый ключ по которому выбирается нужная функция.

Более того, похоже, ты не понимаешь того, что это в любом случае откомпилированный ранее написаный код. Т.е. еще на этапе написания программы ты ДОЛЖЕН создать все функции, ссылки на которые собираешься использовать. А как выбирать нужную функцию... я для примера просто показал как можно выбрать по номеру.

Если ты хочешь вызывать некоторую динамическую функцию, то тогда надо копать в сторону скриптового языка, типа FastScript и т.д. Есть еще один вариант. Использования dll, но там придется городить огород, т.е. dll, для каждой функции и все-равно делать загрузку нужного модуля по его имени.
Ответить с цитированием
  #6  
Старый 27.01.2012, 11:30
shhmn shhmn вне форума
Прохожий
 
Регистрация: 27.01.2012
Сообщения: 6
Репутация: 10
По умолчанию

Цитата:
Сообщение от Pyro
а если объект с функцией типа TFunc ?

Объект действительно подходит, но хотелось бы без него.
Одна из причин - ссылка на метод объекта требует вид

Код:
TFunc = function(x:real):real of object;

что, вроде как не совсем совместимо с обычным

Код:
TFunc = function(x:real):real;

в смысле нельзя подставить в функцию с аргументом второго типа аргумент первого типа
Ответить с цитированием
  #7  
Старый 27.01.2012, 11:50
shhmn shhmn вне форума
Прохожий
 
Регистрация: 27.01.2012
Сообщения: 6
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Здесь Num - просто некоторый ключ по которому выбирается нужная функция.

Более того, похоже, ты не понимаешь того, что это в любом случае откомпилированный ранее написаный код. Т.е. еще на этапе написания программы ты ДОЛЖЕН создать все функции, ссылки на которые собираешься использовать. А как выбирать нужную функцию... я для примера просто показал как можно выбрать по номеру.

Я хотел бы с вещественным типом параметра (т.е. с типом большого диапазона), а твой пример не совсем об этом.

Есть вариант (сложный) - это в функции mult выделить блок памяти, написать в него самому (без компилятора) двоичный код функции, где также зарезервировано место для переменной a, которую инициализируешь нужным значением. Потом возвращаешь указатель на этот блок памяти, как адрес функции.

Только это кажется не рациональным - потому что, грубо говоря, делаешь работу компилятора и трудно потом модифицировать и связывать с др. участками кода. Хотя может как-то можно сделать такую динамическую компиляцию средствами среды?

В итоге я реализовал двумя способами: с объектами и с глобальной переменной. Но с объектом получался другой тип возвращаемой функции, а с глобальной переменной бывали проблемы и не удобно.

Последний раз редактировалось shhmn, 27.01.2012 в 11:52.
Ответить с цитированием
  #8  
Старый 27.01.2012, 12:56
shhmn shhmn вне форума
Прохожий
 
Регистрация: 27.01.2012
Сообщения: 6
Репутация: 10
По умолчанию

Кратко скажу для чего это было нужно. Есть модуль с полезной функцией C0...


Код:
type
  TMatrix = array of array of Extended;          // матрица
  TFurie = function(n1,n2:integer):Extended;      // двумерные Фурье коэффициенты

function C0(mu, ro: TFurie; N;integer): TMatrix;  // возвращает NxN матрицу, которая
                                                  // соответствует
                                                  // волновому уравнению -\ro^{-1}\nabla\mu\nabla u
                                                  // у неё мы будем считать собственные   
                                                  // числа

//////////////////////////////////////////////

function mu(m0,m1,f:Extended):TFurie;            // вот их хотелось бы реализовать!!!
function ro(r0,r1,f:Extended):TFurie;            // они возвращают функции,
                                                  // соответствующие коэффициентам Фурье
                                                  // для области: маленький квадрат
                                                  // площади f и значениями m1,r1
                                                  // симметрично расположенном
                                                  // в большом квадрате площади 1 и
                                                  // значениями в прослойке m0,r0
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 16:30.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter