Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.08.15;
Скачать: CL | DM;

Вниз

вызов функций с разным количеством аргументов?   Найти похожие ветки 

 
miha29   (2004-07-29 13:12) [0]

Доброго дня.
Подскажите пожста, ответ на следующую проблему:

есть метод бисекции, которому необходимо передавать функцию для вычисления её корня на

заданном интервале. Этот метод определен в отдельном классе и вызывается другими методами из

других классов, причем в качестве функции ему должны передаваться тоже функции, определенные

в разных классах -> с разным (!) количеством параметров.
Не получается сделать универсальный тип функции в параметрах метода бисекции, такой чтобы не

приходилось переопределять каждую вызываемую функцию под тип функции бисекции (максимум на

что я согласен :) - это сделать в каждом классе одну (!) функцию которая сделает необходимое

приведение по количеству параметров).

Изиняюсь за путанное объяснение. Я делаю так:
в первом модуле:

 TmMath = class
     eps: double;
    function bisect(f: tfunc; rmin, rmax, eps: double): double;
......
 end
function TMMath.bisect;
var i: integer;
   fmin, fmax, h: double;
   sign: boolean;
begin
  i:=0; sign:=false;
    while (abs(rmax - rmin) - eps>0) do begin
       h:=(rmin + rmax)/2.0;
//здесь может стоять функция не с одним аргументом, соответственно rmax, rmin векторного

//типа, но как быть с tfunc?
       fmin:=f(rmin); fmax:=f(h);
         if fmin*fmax<0 then begin sign:=true; rmax:=h end
            else rmin:=h;
    end;
     if not sign then begin result:=0; exit; end else result:=h;
end;

во втором модуле:

type
  tfunc = function(xi, T: double): double of object far;
в третьем модуле:
 TmLPhase = class (TmPhase)
    function dG(xi, T: double): double; override; //здесь такой же тип как и tfunc
...
 end;

 TmL1Phase = class (TmPhase)
    function dG(xi, T, h: double): double; override; //тоже нужно использовать бисекцию

//(tfunc здесь не проходит)
...
 end;

использование в программе:

a:=mmath.bisect(mLPhase.dG, 0, 5, 1e-4);
b:=mmath.bisect(mL1Phase.dG, 0, 5, 1e-4); //несоответствие типа функции.....


 
Reindeer Moss Eater ©   (2004-07-29 13:20) [1]

Параметрами что выступает, вещественные числа?

function MyFunction(const Data; AItemCount: Word) : TMyResult;


 
TUser ©   (2004-07-29 13:24) [2]

overload
еще можно передавать множество или динамический массив


 
имя   (2004-07-29 17:47) [3]

Удалено модератором


 
panov ©   (2004-07-29 17:56) [4]

А если так, например:

function MyFunc(arg1: Double=0;arg2: Double=0;arg3: Double=0;arg4: Double=0;arg5: Double=0): Double;

Обращение:

MyFunc(10.1,2);
MyFunc(1);
MyFunc(1,1,1,1);

??


 
Анонимщик ©   (2004-07-29 18:27) [5]

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


 
panov ©   (2004-07-29 18:41) [6]

А самое простое - передавать открытый массив в качестве параметра.


 
miha2   (2004-07-30 12:41) [7]

наверное, я неконкретно выразился....

передавать массив в качестве аргумента - не пойдет, параметры передать не проблема, проблема в передаче функции (у которой может быть 1, 2 и т.д. аргументов) . Например:

type
tvec = array of double;
tf1 = function(x: double): double of object;
tf2 = function(x, x1: double): double of object;

var
function bisect(f: tf1; x: double): double;

function TMyObj.root(func: tf1; p: tvec): double;
begin
...
result:={мат метод - находит корень функции 1-й переменной}mmath.bisect(func, p[0]);
end;

function TMyObj.root(func: tf2; p: tvec): double;
var f2: tf1;
begin
...
{здесь как-то нужно преобразовать func в f2}{внутри бисекции происходит вызов функции одной переменной, можно было бы сделать указатель (еще вопрос как?) на нужный процедурный тип и потом просто подменять, но как тогда быть с передачей параметров?}
result:={мат метод - находит корень функции 1-й переменной}mmath.bisect(f2, p[1]);
end;


...проблема грамотно все это объявить и сделать приведение процедурных типов... если так можно выразиться


 
miha2   (2004-07-30 12:46) [8]

еще уточню :)
нужно не передавать разное количество аргументов функции,
а передавать в функцию-1 функцию-2 как аргумент, причем функция-2 в разных классах определена с разным кол-вом аргументов.
Overload делать очень не хочется! (так уже сделано, но кривость и объем кода бесит)


 
GuAV ©   (2004-07-30 12:52) [9]

type tf = function(x: array of double): double of object;

в функциях f1, f2 вместо x1, x2, x3, ...  юзать x[0], x[1], x[2] ...

и тогда никого не надо приводить.
вызывать так: r:=fnc([a, b, c]);


 
Sandman25 ©   (2004-07-30 12:53) [10]

Лучше const x: array of double.
Если, конечно, не нужно изменять аргументы


 
GuAV ©   (2004-07-30 13:19) [11]


> нужно не передавать разное количество аргументов функции,
> а передавать в функцию-1 функцию-2 как аргумент, причем
> функция-2 в разных классах определена с разным кол-вом аргументов.

А как вызвать функцию-2 переданную как аргумент, если в разных классах она определена с разным кол-вом аргументов, и при этом нужно не передавать разное количество аргументов функции?


 
dtm   (2004-07-30 15:03) [12]

А VarArray тут не поможет ?



Страницы: 1 вся ветка

Текущий архив: 2004.08.15;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.046 c
4-1088700317
Green Zmiy
2004-07-01 20:45
2004.08.15
Мастера помогите, нужен жук на COM - порт


14-1090766789
Gero
2004-07-25 18:46
2004.08.15
Иконки IE


14-1091102608
Vovchik_A
2004-07-29 16:03
2004.08.15
Внимание вопрос !


3-1089280127
Ted
2004-07-08 13:48
2004.08.15
Помогите с запросом sql. Заранее благодарен


6-1084746834
w666w
2004-05-17 02:33
2004.08.15
ПОМОГИТЕ!!! как прикрутить к IEParser у события WebBrowser а