Как передать указатель на функцию класса
От: maxidroms Россия  
Дата: 05.05.06 08:39
Оценка:
Есть один клас... в нем есть метод writeToMes(MYPROC proc);


Вызвав этот метод я передаю ему функцию ТИПА MYPROC которая определена в глобальной области видимости (консольный проект)..
Эта функция будет вызываться при наступлении определенных событиях.

Но если создать класс и в нем определить функцию ТИПА MYPROC то передать указатель на нее в writeToMes не удается, если только не сделать ее статической. Статической делать ее не хочу. Ведь работают максросы в MFC типа ON_MESSAGE где можно указать нестатическую функцию.

Подскажите решение плиз. Спасибо!
Re: Как передать указатель на функцию класса
От: Dmitry Kotlyarov Россия  
Дата: 05.05.06 08:49
Оценка:
Здравствуйте, maxidroms, Вы писали:

M>...


Тебе нужно передавать указатель на функцию-член. Кроме того, для осуществления вызова необходим объект класса, членом которого эта функция является. Вызов функции-члена осуществляется с помощью операторов .* и ->* .
Re: Как передать указатель на функцию класса
От: LuciferMoscow Россия  
Дата: 05.05.06 08:55
Оценка:
Здравствуйте, maxidroms, Вы писали:

M>Есть один клас... в нем есть метод writeToMes(MYPROC proc);

что такое MYPROC все догадались?!
<skipped>
Передавай в качестве твоей функции boost::function http://boost.org/doc/html/function.html
и используй boost::bind http://boost.org/libs/bind/bind.html
Re[2]: Как передать указатель на функцию класса
От: maxidroms Россия  
Дата: 05.05.06 08:59
Оценка:
еще раз....



typedef void (*ACC_ONACCEPT)(std::string ipAddress); //Это и есть MYPROC =) извините что так выразился

вот пример:

ТАК работает

CNETEngine net; //Это сетевой движок

void onAcc(std::string str){       //Метод, который будет вызываться
    MessageBox(0,str.data(),0,0);
}

int main(){
    
    net.WSAInit();                     // Инициализируем WSA
    net.mne_startServer(4567);         // Открываем порт на прослушиваение. в сетевом движке создается поток...ожидающий соединения..      net.mne_writeTo_OnAccept(onAcc);              //Сообщаю движку какой метод надо вызвать, когда произойдет соединение

               //когда соединение происходит...сокет добавляется в список обслуживаемых и вызывается onAcc , в качестве параметра передается IP адрес присоединеного клиента


    MessageBox(0,"server started",0,0);
    
    return 0;
}


так тоже работает но я так не хочу =)

CNETEngine net; //Это сетевой движок

class test{
   public:
   static void onAcc(std::string str);
}
void test::onAcc(std::string str){       //Метод, который будет вызываться
    MessageBox(0,str.data(),0,0);
}

int main(){
    test t;
    net.WSAInit();                     // Инициализируем WSA
    net.mne_startServer(4567);         // Открываем порт на прослушиваение. в сетевом движке создается поток...ожидающий соединения..      net.mne_writeTo_OnAccept(t.onAcc);              //Сообщаю движку какой метод надо вызвать, когда произойдет соединение

               //когда соединение происходит...сокет добавляется в список обслуживаемых и вызывается onAcc , в качестве параметра передается IP адрес присоединеного клиента


    MessageBox(0,"server started",0,0);
    
    return 0;
}
Re[2]: Как передать указатель на функцию класса
От: maxidroms Россия  
Дата: 05.05.06 09:02
Оценка:
Здравствуйте, LuciferMoscow, Вы писали:

LM>Здравствуйте, maxidroms, Вы писали:


M>>Есть один клас... в нем есть метод writeToMes(MYPROC proc);

LM>что такое MYPROC все догадались?!
LM><skipped>
LM>Передавай в качестве твоей функции boost::function http://boost.org/doc/html/function.html
LM>и используй boost::bind http://boost.org/libs/bind/bind.html

ИЖВИНИТЕ
http://www.rsdn.ru/Forum/Message.aspx?mid=1883777&amp;only=1
Re[3]: Как передать указатель на функцию класса
От: LuciferMoscow Россия  
Дата: 05.05.06 09:11
Оценка:
Здравствуйте, maxidroms, Вы писали:
<skipped>
M>ИЖВИНИТЕ
M>http://www.rsdn.ru/Forum/Message.aspx?mid=1883777&amp;only=1
Да понял я суть проблемы Все равно boost тебя спасет
Re[4]: Как передать указатель на функцию класса
От: maxidroms Россия  
Дата: 05.05.06 09:15
Оценка:
Здравствуйте, LuciferMoscow, Вы писали:

LM>Здравствуйте, maxidroms, Вы писали:

LM><skipped>
M>>ИЖВИНИТЕ
M>>http://www.rsdn.ru/Forum/Message.aspx?mid=1883777&amp;only=1
LM>Да понял я суть проблемы Все равно boost тебя спасет

Неужели единственное решение?
Re[3]: Как передать указатель на функцию класса
От: Bell Россия  
Дата: 05.05.06 09:35
Оценка:
Здравствуйте, maxidroms, Вы писали:


Я так понял, что этот самый сетевой движок менять ты не можешь. А значит, и передать указатель на метод класса не сможещь, так указатель на метод класса и указатель на обычную функцию — вещи разные. Кроме того, для вызова метода класса необходим объект этого самого класса.

Вот простейший переходник:

class my_cls;
struct redir
{
   static my_cls* ptr;
   static void func();
};

my_cls* redir::ptr = 0;

class my_cls
{
public:
   void f() {}
};

void redir::func()
{
   ptr->f();
}
int main()
{
   my_cls obj;
   redir::ptr = &obj;
   //теперь можно использовать redir::func
   return 0;
}



Еще можешь пойти в поиск и набрать

функция + член + передать + поток

Любите книгу — источник знаний (с) М.Горький
Re[4]: Как передать указатель на функцию класса
От: zaufi Земля  
Дата: 05.05.06 09:39
Оценка:
Здравствуйте, Bell, Вы писали:
B>Еще можешь пойти в поиск и набрать
B>

B>... + член + ...


о да! интересных сайтов найдешь оч много
Re[5]: Как передать указатель на функцию класса
От: Bell Россия  
Дата: 05.05.06 09:43
Оценка:
Здравствуйте, zaufi, Вы писали:

Z>о да! интересных сайтов найдешь оч много


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

ЗЫ
У кого что болит...
Любите книгу — источник знаний (с) М.Горький
Re[5]: Как передать указатель на функцию класса
От: LuciferMoscow Россия  
Дата: 05.05.06 10:36
Оценка:
Здравствуйте, maxidroms, Вы писали:
LM>>Да понял я суть проблемы Все равно boost тебя спасет
M>Неужели единственное решение?
Почти.

Другие варианты:
1. Добавить в callback параметр "Указатель на класс" и в твоем статическом callback-е вызывать нестатический
// Статическая функция!
void SomeClass::StaticCallBack( SomeSlass* ptr, /*some more arguments*/)
{
   ptr->NonstaticCallback(/*some more arguments*/);
}


2. Сделать твой SomeClass синглетоном
// Статическая функция!
void SomeClass::StaticCallBack( /*some more arguments*/)
{
SomeClass& ref=SomeClass::instance();
ref.NonstaticCallback(/*some more arguments*/);
}
[/ccode]

А почему буст пугает? Он не страшный и совсем не кусается.
Re[6]: Как передать указатель на функцию класса
От: maxidroms Россия  
Дата: 05.05.06 10:40
Оценка:
Здравствуйте, LuciferMoscow, Вы писали:

LM>Здравствуйте, maxidroms, Вы писали:

LM>>>Да понял я суть проблемы Все равно boost тебя спасет
M>>Неужели единственное решение?
LM>Почти.

LM>Другие варианты:

LM>1. Добавить в callback параметр "Указатель на класс" и в твоем статическом callback-е вызывать нестатический
LM>
LM>// Статическая функция!
LM>void SomeClass::StaticCallBack( SomeSlass* ptr, /*some more arguments*/)
LM>{
   ptr->>NonstaticCallback(/*some more arguments*/);
LM>}
LM>


LM>2. Сделать твой SomeClass синглетоном

LM>// Статическая функция!
LM>void SomeClass::StaticCallBack( /*some more arguments*/)
LM>{
LM> SomeClass& ref=SomeClass::instance();
LM> ref.NonstaticCallback(/*some more arguments*/);
LM>}
LM>[/ccode]

LM>А почему буст пугает? Он не страшный и совсем не кусается.



Как всегда...хочется много и сразу (дешево и сердито)

напугали меня неведомые конструкции буста... задача простая...думаю решение такое же должно быть...нуна чтоб сетевой движок информировал о своих выполненых действиях (приконнектились, закончили получать данные и пр.)
хочу что то делегатов в C#
Re[4]: Как передать указатель на функцию класса
От: maxidroms Россия  
Дата: 05.05.06 10:44
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, maxidroms, Вы писали:



B>Я так понял, что этот самый сетевой движок менять ты не можешь. А значит, и передать указатель на метод класса не сможещь, так указатель на метод класса и указатель на обычную функцию — вещи разные. Кроме того, для вызова метода класса необходим объект этого самого класса.


B>Вот простейший переходник:


B>
B>class my_cls;
B>struct redir
B>{
B>   static my_cls* ptr;
B>   static void func();
B>};

B>my_cls* redir::ptr = 0;

B>class my_cls
B>{
B>public:
B>   void f() {}
B>};

B>void redir::func()
B>{
   ptr->>f();
B>}
B>int main()
B>{
B>   my_cls obj;
B>   redir::ptr = &obj;
B>   //теперь можно использовать redir::func
B>   return 0;
B>}
B>



B>Еще можешь пойти в поиск и набрать

B>

B>функция + член + передать + поток


Нет... класс тоже мой... тока разрабатываю... хочу чтоб для меня удобней был... типа AsyncSelect хочу....
поэтому менять могу... объясните как указатель мона на метод класса передавать?
Re[6]: Как передать указатель на функцию класса
От: Аноним  
Дата: 05.05.06 10:50
Оценка: 2 (1)
LM>Другие варианты:

3. Передавать не callback-функцию, а callback-интерфейс

struct ICallback
{
virtual void OnCallback(/* параметры callbac'а*/) = 0;
};


void XXX::writeToMes(ICallback *cb);
Re[7]: Как передать указатель на функцию класса
От: Alex_Avr Россия  
Дата: 05.05.06 10:55
Оценка:
Здравствуйте, maxidroms, Вы писали:

M>хочу что то делегатов в C#

Посмотри здесь
С уважением, Александр Авраменко.
Re: Как передать указатель на функцию класса
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 05.05.06 11:06
Оценка:
Здравствуйте, maxidroms, Вы писали:

M>Есть один клас... в нем есть метод writeToMes(MYPROC proc);


M>Подскажите решение плиз. Спасибо!


здесь
Автор: Коваленко Дмитрий
Дата: 28.01.02


Вот как раз сижу и подготавливаю исходники для перехода с BCB5 на VS — изничтожаю использование Borland-специчной штуки по имени __closure

Смысл: объект класса TSTD_RowsetProperties генерирует уведомление, которое получает и обрабатывает объект класса TIBCommand

//ib_props.h ------------------------------------
class TSTD_RowsetProperties
{
 //....
 typedef structure::t_closure_1<bool> TOnUseBookmarkChange;

 TOnUseBookmarkChange OnUseBookmarkChange;
};//class TSTD_RowsetProperties

//ib_props.cpp ----------------------------------
void TSTD_RowsetProperties::SetUseBookmark(const bool value)
{
 //...
 if(OnUseBookmarkChange)
  OnUseBookmarkChange(value);
}//SetUseBookmark

//ib_command.h ----------------------------------
class TIBCommand
{ 
 //....
 void EvIBPropUseBookmarkChange(bool value);
};//class TIBCommand

//ib_command.cpp --------------------------------
HRESULT TIBCommand::Init()
{
 //....
 //отслеживаем изменения свойств
 m_spStdProps->OnUseBookmarkChange=
  structure::make_closure(this,&TIBCommand::EvIBPPropUseBookmarkChange);//включение закладок
}//Init

void TIBPCommand::EvIBPPropUseBookmarkChange(bool value)
{
 //...
}//EvIBPropUseBookmarkChange
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[7]: Как передать указатель на функцию класса
От: maxidroms Россия  
Дата: 05.05.06 11:17
Оценка:
Здравствуйте, Аноним, Вы писали:


LM>>Другие варианты:


А>3. Передавать не callback-функцию, а callback-интерфейс


А>struct ICallback

А>{
А> virtual void OnCallback(/* параметры callbac'а*/) = 0;
А>};


А>void XXX::writeToMes(ICallback *cb);



И где должна распологаться структура? в классе сетевого движка или в файле, в котором я использую этот движок?
Re[7]: Как передать указатель на функцию класса
От: LuciferMoscow Россия  
Дата: 05.05.06 11:35
Оценка:
Здравствуйте, Аноним, Вы писали:
LM>>Другие варианты:
А>3. Передавать не callback-функцию, а callback-интерфейс
А>struct ICallback
А>{
А> virtual void OnCallback(/* параметры callbac'а*/) = 0;
А>};
А>void XXX::writeToMes(ICallback *cb);
Вариант интересный, но что делать если один класс должен поддерживать 10 разных callback-ов?
Re[5]: Как передать указатель на функцию класса
От: Bell Россия  
Дата: 05.05.06 11:41
Оценка: 3 (1)
Здравствуйте, maxidroms, Вы писали:


M>Нет... класс тоже мой... тока разрабатываю... хочу чтоб для меня удобней был... типа AsyncSelect хочу....

M>поэтому менять могу... объясните как указатель мона на метод класса передавать?

Тогда бери boost::function и вперед:

class CNETEngine
{
   boost::function<void (const string&)> f_;
public:
   void mne_writeTo_OnAccept(boost::function<void (const string&)> f)
   {
      f_ = f;
   }

   void test(const string& s)
   {
      f_("bla-bla-bla");
   }
};

void f(const string& s)
{
   cout << "::f " << s << '\n';
}

class test
{
public:
   void f(const string&  s)
   {
      cout << "test::f " << s << '\n';
   }

   void operator()(const string&  s)
   {
      cout << "test::operator() " << s << '\n';
   }
};

int main()
{
   CNETEngine e;
   //Обычная функция
   e.mne_writeTo_OnAccept(f);
   e.test("1");

   test t;
   //Функция-член
   e.mne_writeTo_OnAccept(boost::bind(&test::f, &t, _1));
   e.test("2");

   //Объект-функтор
   e.mne_writeTo_OnAccept(t);
   e.test("4");
   return 0;
}
Любите книгу — источник знаний (с) М.Горький
Re[8]: Как передать указатель на функцию класса
От: Аноним  
Дата: 05.05.06 11:52
Оценка:
LM>>>Другие варианты:

А>>3. Передавать не callback-функцию, а callback-интерфейс


А>>struct ICallback

А>>{
А>> virtual void OnCallback(/* параметры callbac'а*/) = 0;
А>>};


А>>void XXX::writeToMes(ICallback *cb);



M>И где должна распологаться структура? в классе сетевого движка или в файле, в котором я использую этот движок?


Там где ты его используешь.
Причём не то, чтобы располагаться, от неё надо наследоваться и реализовывать метод OnCallback(), который потом будут у тебя вызывать.

А движок потом сможет тебя вызвать:

void XXX::writeToMes(ICallback *cb)
{
   ....
   cb->OnCallback(...);
   ....
}


Естественно, надо быть осторожным, и не сохранять у себя этот указатель дольше, чем существует объект, на который он указывает.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.