На информационном ресурсе применяются cookie-файлы. Оставаясь на сайте, вы подтверждаете свое согласие на их использование.
Передача математической зависимости
1820
10
Есть несколько неких математических зависимостей - функций - для расчета одной величины разными методами. Нужна такая реализация, при которой бы на основе каких-либо условий выбиралась та или иная функция (метод расчета). Основная сложность кроется в том, что содержание расчетов, соответствующих этим функциям заведомо не известно и должно передаваться программе через специальный интерфейс, принимающий параметры для расчета.
Так вот, каким образом передать в этот интерфейс (принимающую функцию), например, такое:
y = 2*x - 10
Может, стоит, использовать указатель на функцию? Подскажите, кто сталкивался с подобной задачей.
Так вот, каким образом передать в этот интерфейс (принимающую функцию), например, такое:
y = 2*x - 10
Может, стоит, использовать указатель на функцию? Подскажите, кто сталкивался с подобной задачей.
Что же является критерием для выбора той или иной функции (метода)? Можно и switch использовать.
А на чем предполагается писать? С++?
Да. C++, среда VS6.
Вообще, как я понял, для подобной реализации вполне приемлемо использовать указатель на функцию. Осталась единственная проблема, которую пока не знаю как решить - как прописать принимающей функции в качестве параметра указатель на функцию. При использовании ClassWizard'a вариант типа float y(float x, float (*func)(float xval)); не предусмотрен. А при попытке менять типы вручную возникают ошибки.
Вообще, как я понял, для подобной реализации вполне приемлемо использовать указатель на функцию. Осталась единственная проблема, которую пока не знаю как решить - как прописать принимающей функции в качестве параметра указатель на функцию. При использовании ClassWizard'a вариант типа float y(float x, float (*func)(float xval)); не предусмотрен. А при попытке менять типы вручную возникают ошибки.
Во-первых, я все еще не понял тонкостей задания. Есть контроллер, который принимает некие параметры (фиксированный набор или произвольный?) и вызывает некую функцию (передается вместе с параметрами или должен сам выбрать?)
Во-вторых, какого рода ошибки вылазят?
Во-вторых, какого рода ошибки вылазят?
Есть контрол, функция(интерфейс) которого принимает:
а) аргумент функции(некоей мат. зависимости)
б) саму мат. зависимость
В основном коде прописывается зависимость в виде функции:
float y(float curx)
{
float yres = curx*curx;
return yres;
}
Там же объявляется указатель на эту функцию:
float (*ptr)(float x) = y;
Далее в контрол передается значение аргумента, и зависимость, в соответствии с которой его нужно просчитать:
ControlName->CalcFunc(2.15, ptr);
Теперь нужно принять это значение функцией контрола:
float CalcFunc(float xcur, float (*func)(float x))
{
float ydst = func(xcur);
return ydst;
}
Добавление функции, видной извне, в контрол (функции интерфейса) производится через ClassWizard VS6. Там необходимо указать типы входящих данных путем выбора из списка. Как сделать это для случая с float (*func)(float x)) мне совсем неясно.
Вот, собственно, формулировка вопроса.
а) аргумент функции(некоей мат. зависимости)
б) саму мат. зависимость
В основном коде прописывается зависимость в виде функции:
float y(float curx)
{
float yres = curx*curx;
return yres;
}
Там же объявляется указатель на эту функцию:
float (*ptr)(float x) = y;
Далее в контрол передается значение аргумента, и зависимость, в соответствии с которой его нужно просчитать:
ControlName->CalcFunc(2.15, ptr);
Теперь нужно принять это значение функцией контрола:
float CalcFunc(float xcur, float (*func)(float x))
{
float ydst = func(xcur);
return ydst;
}
Добавление функции, видной извне, в контрол (функции интерфейса) производится через ClassWizard VS6. Там необходимо указать типы входящих данных путем выбора из списка. Как сделать это для случая с float (*func)(float x)) мне совсем неясно.
Вот, собственно, формулировка вопроса.
1. Если вариантов функций немного, это классический вариант паттерна Strategy.
2. Если хочется поиметь любое выражение, то это Interpreter: распарсить строку по грамматике, поиметь AST-дерево и Command-ами/Visitor-ами его посчитать.
2. Если хочется поиметь любое выражение, то это Interpreter: распарсить строку по грамматике, поиметь AST-дерево и Command-ами/Visitor-ами его посчитать.
Сейчас читают
Ассоциации игра (часть 60)(NF)
236862
1000
Ассоциации игра (часть 61)(NF)
219358
1000
ПомПа или термостат?
12112
111
Думается, можно обойтись более простой реализацией. Неоднократно слышал положительные отзывы о design patterns, но в них я не секу.
Зато появилась мысль, сводящая проблему к менее объемной.
В общем так.
Функция интерфейса ActiveX-контрола ждет зависимости, по которой булет производится дальнейший расчет.
Из основной программы в контрол передается указатель она функцию, сконвернутый в int.
Примерно так:
float (*ptr)(float) = func; // func - функция, которую надо передать контролу
MyControl1->MyFunction((int)ptr);
Соответственно, теперь требуется на стороне контрола получить из переменной типа int значение типа "указатель на функцию".
Как такое осуществить? Был бы какой-нить char* - там понятно:
MyFunction(int myptr)
{
char* pp = (char*)myptr;
}
А указатель на функцию так просто, похоже, из адреса не получить.
Зато появилась мысль, сводящая проблему к менее объемной.
В общем так.
Функция интерфейса ActiveX-контрола ждет зависимости, по которой булет производится дальнейший расчет.
Из основной программы в контрол передается указатель она функцию, сконвернутый в int.
Примерно так:
float (*ptr)(float) = func; // func - функция, которую надо передать контролу
MyControl1->MyFunction((int)ptr);
Соответственно, теперь требуется на стороне контрола получить из переменной типа int значение типа "указатель на функцию".
Как такое осуществить? Был бы какой-нить char* - там понятно:
MyFunction(int myptr)
{
char* pp = (char*)myptr;
}
А указатель на функцию так просто, похоже, из адреса не получить.
Я сейчас проверить не могу, но могу дать такой совет - на ClassWizard забить, написать простой код ручками и посмотреть, что получится. Если нормально с английским, можно почитать здесь:
http://www.function-pointer.org/fpt.html#passPtr
P.S. Передача указателя, сконвертированного в int, покатит, но это уже лишнее.
http://www.function-pointer.org/fpt.html#passPtr
P.S. Передача указателя, сконвертированного в int, покатит, но это уже лишнее.
1. За линку спасибо, приятно было ознакомиться с хорошо структурированным материалом по теме. Однако принципиальных идей подчерпнуть не удалось - и так выполняю все по описанному там варианту передачи указателя на функцию в качестве аргумента.
2. При попытке забить на ClassWizard вручную аргументы (их типы) функции замечательно редактируются в cpp и h файлах проекта,
Там они после внесения изменений имеют вид:
float (*func)(float).
Однако в odl-файле, то есть там, где прописаны все эти выходы функций наружу (интерфейсы), ни в какую не канает вариант float (*func)(float)
Ошибка: error MIDL2094 : [id] attribute is required : [( Parameter 'func' ) ]
Блин, мне все равно думается, что можно таким способом реализовать данную функциональность. Тока как совладать с odl-связями?
2. При попытке забить на ClassWizard вручную аргументы (их типы) функции замечательно редактируются в cpp и h файлах проекта,
Там они после внесения изменений имеют вид:
float (*func)(float).
Однако в odl-файле, то есть там, где прописаны все эти выходы функций наружу (интерфейсы), ни в какую не канает вариант float (*func)(float)
Ошибка: error MIDL2094 : [id] attribute is required : [( Parameter 'func' ) ]
Блин, мне все равно думается, что можно таким способом реализовать данную функциональность. Тока как совладать с odl-связями?
ТОП 5
1
3