Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Передача указателя внутри класса без static. 
:(
    Опции темы
UDT
Дата 25.10.2014, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 25.10.2014

Репутация: нет
Всего: нет



Товарищи, помогите с   программой, пожалуйста.
Есть класс, в котором приват-функции Integrate(...)  нужно передать  указатель на приват-функцию Integrand(...).
Передача адреса тут необходима согласно декларации gsl-function из Integrate(...), смотреть строчку 44 в полном коде.
На все мои попытки присвоить адрес Integrand, типа чего-то такого
Код
gsl_function F;
  F.function=&Integrand;
  F.params=data;
, компилятор ругается.

На этот момент, с момощью определения указателя вне класса 
Код

//Pointer definition//    
double (cross_section::*pt_to_Integrand)(double y, void *data);
, мне удалось обратиться к фунции Integrand из другой фукции Print того же класса 
Код

void cross_section::print(){
integration_params parameters;
parameters.a=1.0;
parameters.b=1.0;
pt_to_Integrand=&cross_section::Integrand;
printf("Here we call the function integrand by the pointer from CS.print \n"
        "Integrand = % .18f\n",(this->*pt_to_Integrand)(0.1,&parameters));
}
.
Однако, предать указатель gsl-функции  не получается. Например, так не работает 
Код
gsl_function F;
  F.function=(this->pt_to_Integrand);
  F.params=data;


Что не так? 
Пожалуйста, не предлагайте решения, требующие С++11 и выше. Введения static function тоже хочется избежать.
Очень надеюсь на помощь, спасибо.

Вот полный код  
Код

#include <iostream>
#include <stdio.h>
#include <stdlib.h>     /* getenv */
#include <math.h>
#include <string>
#include <gsl/gsl_integration.h>
using namespace std;

//Class definition//
class cross_section{
  private:   
    struct integration_params{double a;double b;};
    double Integrand(double y, void*data);
    double Integrate(integration_params*data);
    
    public:
    //cross_section();
    void print();
   // double Sigma(integration_params*data);
    };

//Pointer definition//    
double (cross_section::*pt_to_Integrand)(double y, void *data);
  

//Class members//
double cross_section::Integrand(double y, void* data){
  integration_params data_y=*(integration_params*)data;
  double a=data_y.a;
  double b=data_y.b;
  return a*exp(-y*y*b);
}

double cross_section::Integrate(integration_params *data){

  int integ_space=1000;
  gsl_integration_workspace *workspace;
  workspace= gsl_integration_workspace_alloc(integ_space);
  double abserr;
  double result;
  double rel_error = 1e-3;
  double abs_error = 1e-3; 
  gsl_function F;
  F.function=(this->pt_to_Integrand);
  F.params=data;
  
  gsl_integration_qag(&F,-1.0,1.0,abs_error,rel_error,integ_space,5,workspace,&result,&abserr) ;
  gsl_integration_workspace_free (workspace);
  return result;
}

void cross_section::print(){
integration_params parameters;
parameters.a=1.0;
parameters.b=1.0;
pt_to_Integrand=&cross_section::Integrand;
printf("Here we call the function integrand by the pointer from CS.print \n"
        "Integrand = % .18f\n",(this->*pt_to_Integrand)(0.1,&parameters));
}


// Main part//
int main(){
 cross_section CS;
 CS.print();
return 0;}


PM MAIL   Вверх
borisbn
Дата 26.10.2014, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Я в таких случаях делаю след. образом
Код
class cross_section {
    void Integrand() {
        ...
    }
    static void s_Integrand( void * context ) {
        cross_section * self = (cross_section *)context;
        self->Integrand();
    }
    void print(){
        gsl_function F;
        F.function=& cross_section::s_Integrand;
        F.params=this;
        // Do what you want with F
};

Если в функцию Integrand() нужно передавать параметры, то их нужно сохранить в члене класса cross_section, а при вызове брать их и подставлять в Integrand( ... ). Т.е. типа такого
Код
class cross_section {
    void Integrand( int x ) {
        ...
    }
    static void s_Integrand( void * context ) {
        cross_section * self = (cross_section *)context;
        self->Integrand( m_saved_x );
    }
    void print(){
        gsl_function F;
        F.function=& cross_section::s_Integrand;
        F.params = this;
        m_saved_x = 42;
        // Do what you want with F
};



Это сообщение отредактировал(а) borisbn - 26.10.2014, 12:38


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
UDT
Дата 26.10.2014, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 25.10.2014

Репутация: нет
Всего: нет



borisbn,  спасибо за ответ. Как раз статик-функцию не хотелось вводить. Хочу чтобы наружу из класса торчала только одна функция. Мне придется делать  несколько вложенных интегрирований и, на каждое вводить свою static как pablic-функцию, что-то не хочется.
Может кто еще что подскажет?  
PM MAIL   Вверх
Ihost
Дата 27.10.2014, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 14.9.2012

Репутация: нет
Всего: нет



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

typedef double (cross_section::*pt_to_Integrand)(double y, void *data);
, хоть даже внутри того же класса
Полезную информацию можно прочесть здесь - Самые быстрые делегаты на C++
PM MAIL   Вверх
UDT
Дата 3.11.2014, 23:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 25.10.2014

Репутация: нет
Всего: нет



Ihost, большое спасибо.
Делегаты-это как раз то, что нужно!  
Пока, лучшее что  у меня выходило это объявить Integrand as а static-function.  
Пойду переделывать, спасибо еще раз. 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1991 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.