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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Классы: как "организовать" такой код? 
V
    Опции темы
Alca
Дата 12.12.2009, 20:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Код

void vOnExitHandle() {
    //...
}
//...
CWorkThread *pthThread = new CWorkThread();
pthThread->m_uiIndex = i;
pthThread->vOnExit   = vOnExitHandle;    //как "организовать" такой код ???

pthThread->bCreate();
pthThread->bResume();



--------------------
PM WWW ICQ Skype Jabber   Вверх
Alexeis
Дата 12.12.2009, 20:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



Alca, вопрос в чем? Как создавать обработчики или как выполнить финальный обработчик контексте основного потока?


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alca
Дата 12.12.2009, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Как создавать обработчики

Добавлено через 1 минуту и 47 секунд
Код

pthThread->vOnExit = ...



--------------------
PM WWW ICQ Skype Jabber   Вверх
Alexeis
Дата 12.12.2009, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



объявить в классе переменную указатель на функцию. Примерно так.
Код

...
void (*vOnExit) (void);
...


Добавлено через 1 минуту и 50 секунд
  Эта тема хорошо раскрыта тут http://alenacpp.blogspot.com/2007/04/blog-post.html

Это сообщение отредактировал(а) Alexeis - 12.12.2009, 21:09


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alca
Дата 12.12.2009, 21:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Ок. А как внутри класса CWorkThread "прикрутить" этот указатель?

Это сообщение отредактировал(а) Alca - 12.12.2009, 21:15


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alexeis
Дата 12.12.2009, 21:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



Цитата(Alca @  12.12.2009,  20:15 Найти цитируемый пост)
Ок. А как внутри класса CWorkThread "прикрутить" этот указатель?

  Собственно я это и написал. 
Код

class CWorkThread
{
...
public:
  void (*vOnExit) (void);
...
};
 

А присвоение обработчика уже показано тут 

Цитата(Alca @  12.12.2009,  19:38 Найти цитируемый пост)
pthThread->vOnExit   = vOnExitHandle;    //как "организовать" такой код ???


Именно так и нужно.



--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alca
Дата 12.12.2009, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Сейчас гляну. Спасибо.

Добавлено @ 21:21
Код

class CWorkThread
{
...
public:
  void (*vOnExit) (void);
  void vMethodA() {
      vOnExit();  //надо вызвать метод внутри класса
  }
...
};



Это сообщение отредактировал(а) Alca - 12.12.2009, 21:42


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alexeis
Дата 12.12.2009, 21:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



вызывается по другому
Код

(*vOnExit)();



--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Abyx
Дата 12.12.2009, 21:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



если CWorkThread - часть библиотеки, а обработчик предоставляет пользователь, лучше использовать шаблоны или boost::function<>
PM MAIL   Вверх
Alca
Дата 12.12.2009, 21:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата

если CWorkThread - часть библиотеки, а обработчик предоставляет пользователь, 

 smile 
Цитата

лучше использовать шаблоны или boost::function<>

не хочеться буст прикручивать 


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 12.12.2009, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



а как вызвать vOnExit из статического метода класса?

Добавлено через 12 минут и 1 секунду
вроде так:
Код

...
pthThis->vOnExit(); 
...



--------------------
PM WWW ICQ Skype Jabber   Вверх
Alexeis
Дата 12.12.2009, 22:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



Цитата(Alca @  12.12.2009,  21:33 Найти цитируемый пост)
а как вызвать vOnExit из статического метода класса? 

  Можно, если статический метод получает как параметр указатель на экземпляр объекта.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alca
Дата 12.12.2009, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Со статическим методом вроде разобрался.

пытаюсь присвоить обработчик:
Код

UINT CXThreadPool::uiOnRun(VOID *pData) { 
    ....
    pthThread->vOnExit   = _vOnTest; 
    ...
}
   
Код

Error    1    error C3867: 'CXThreadPool::_vOnTest': function call missing argument list; use '&CXThreadPool::_vOnTest' to create a pointer to member    d:\xlib\source\sync\cxthreadpool.cpp    205
Error    2    error C2440: '=' : cannot convert from 'void (__thiscall CXThreadPool::* )(void)' to 'void (__cdecl *)(void)'    d:\xlib\source\sync\cxthreadpool.cpp    205

 smile

Добавлено @ 22:52
1-ю ошибку исправил
Код

pthThread->vOnExit   = &CXThreadPool::_vOnTest; 

Как вторую решить?
Код

Error    1    error C2440: '=' : cannot convert from 'void (__thiscall CXThreadPool::* )(void)' to 'void (__cdecl *)(void)'    d:\xlib\source\sync\cxthreadpool.cpp    205




Это сообщение отредактировал(а) Alca - 12.12.2009, 22:57


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alexeis
Дата 12.12.2009, 23:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



  Компилятор прав функция класса и функция это разные вещи. функция класса + указатель на объект нам дают уже замыкание. Это совсем другая конструкция. На билдере это делается через расширение языка __closure . В студии тоже что-то такое есть, но я уже не помню 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Леопольд
Дата 13.12.2009, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Alca @  12.12.2009,  21:38 Найти цитируемый пост)
не хочеться буст прикручивать  

Ну, ежели нужен велосипед, то мог бы сойти такой:
Код

#include <iostream>
#include <memory>

class Functor{
public:
    virtual void operator()() const = 0;
    virtual ~Functor(){}
};

class Object{
public:
    void toCall(){
        std::cout<<"Object::toCall is invoked"<<std::endl;
    };

    void toCall() const{
        std::cout<<"const Object::toCall is invoked"<<std::endl;
    };

    Functor* createFunctor(){
        class OFunctor: public Functor{
            Object& _ref;
        public:
            OFunctor(Object& ref): _ref(ref){}
            virtual void operator()() const{
                _ref.toCall();
            }
        };

        return new OFunctor(*this);
    }

    Functor* createFunctor() const{
        class OFunctor: public Functor{
            const Object& _ref;
        public:
            OFunctor(const Object& ref): _ref(ref){}
            virtual void operator()() const{
                _ref.toCall();
            }
        };

        return new OFunctor(*this);
    }
};

int main () {

    Object obj;
    std::auto_ptr<Functor> ptr(obj.createFunctor());
    (*ptr)();

    const Object cobj;
    std::auto_ptr<Functor> cptr(cobj.createFunctor());
    (*cptr)();

    return 0;
}


Это сообщение отредактировал(а) Леопольд - 13.12.2009, 21:50


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Alca
Дата 14.12.2009, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата

Ну, ежели нужен велосипед

Можно попробывать 

Вот мои классы, как этот велик приспособить? 
Код

/****************************************************************************
*    класс CXThread
*
*****************************************************************************/

//---------------------------------------------------------------------------
//CXThread.h
class CXThread {
    //...
    
    public:
        VOID   (*vOnExit)();
    
    protected:
        virtual UINT uiOnRun(VOID *pvParam) = 0;
                
    private:
        static UINT WINAPI _s_uiStartFunc(VOID *pvParam);
    
    //...
};
//---------------------------------------------------------------------------
//CXThread.cpp
/*static*/ UINT WINAPI CXThread::_s_uiStartFunc(VOID *pvParam) {
    CXThread *pthThis = static_cast<CXThread *>(pvParam); 
    pthThis->vOnExit(); 
    
    //...
    
    return uiRes;
}
//---------------------------------------------------------------------------


Код

/****************************************************************************
*    класс CXThreadPool
*
*****************************************************************************/

//---------------------------------------------------------------------------
//CXThreadPool.h
#include <XLib/Sync/CXThread.h>
//---------------------------------------------------------------------------
class CXThreadPool : public CXThread {
    //...
    protected:
        virtual UINT uiOnRun    (VOID *pData);    /*overload from CXThread*/
        
    private:
        std::vector<CWorkThread *> _m_vecpthWorkThreads;
        
        VOID _vOnTest(VOID) {
            ::MessageBox(0, _T("Test"), _T(""), MB_OK);
        }        
    //...        
};
//---------------------------------------------------------------------------
//CXThreadPool.cpp
UINT CXThreadPool::uiOnRun(VOID *pData) { 
    //...
    
    CXThreadPool *pthTemp = new CXThreadPool();
    
    _m_vecpthWorkThreads.at(_m_uiCurrTask) = pthTemp;
    _m_vecpthWorkThreads.at(_m_uiCurrTask)->vOnExit  = &CXThreadPool::_vOnTest; /*<<< здесь ругается:
    Error    1    error C2440: '=' : cannot convert from 'void (__thiscall CXThreadPool::* )(void)' to 'void (__cdecl *)(void)'
    */
    _m_vecpthWorkThreads.at(_m_uiCurrTask)->bCreate();
    _m_vecpthWorkThreads.at(_m_uiCurrTask)->bResume();

    _m_uiCurrTask ++;

    //...

    return uiRes;
}
//---------------------------------------------------------------------------



--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 14.12.2009, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Ну или как с бустом будет?


--------------------
PM WWW ICQ Skype Jabber   Вверх
Леопольд
Дата 14.12.2009, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Alca @  14.12.2009,  11:55 Найти цитируемый пост)
Ну или как с бустом будет? 


Код

#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>

class Invoker{
    typedef boost::function<void ()> Functor;
    Functor _functor;

public:
    template<typename F>
    void setFunctor(F functor){ // Attention! Transmission by value, and not by reference.
        _functor = functor;
    }
    void invoke(){
        _functor();
    }
};

void plainFunction(){
    std::cout<<"function"<<std::endl;
}


struct Object{
    void foo(){
        std::cout<<"Object::foo"<<std::endl;
    }
};

struct FunctObj{
    void operator()(){
        std::cout<<"FunctObj::operator()"<<std::endl;
    }
};

int main(){
    
    Invoker invoker;

    Object obj;
    invoker.setFunctor( boost::bind(&Object::foo, obj) );
    invoker.invoke();
    
    FunctObj fo;
    invoker.setFunctor(fo);
    invoker.invoke();

    invoker.setFunctor(plainFunction);
    invoker.invoke();

    return 0;
}


Должен предупредить что я не использую boost активно. Функторы вообще первый раз в этом примере. Руководствовался статьёй и немного почитал boost.org

Это сообщение отредактировал(а) Леопольд - 14.12.2009, 14:26


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Alca
Дата 14.12.2009, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Леопольд, спасибо. Буду разбираться.


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 14.12.2009, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Код

boost::function<void (CXThreadPool*)> f;
f = &CXThreadPool::_vOnTest;
///f(this);
_m_vecpthWorkThreads.at(_m_uiCurrTask)->_vOnExit  =  f ;   

Код

Error    1    error C2440: '=' : cannot convert from 'boost::function<Signature>' to 'void (__cdecl *)(void)'

 smile

Добавлено через 2 минуты и 9 секунд
Темный лес  smile 


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 14.12.2009, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Решил проблему с помощью Winnie.Closure.


FAQ:
Цитата

- Winnie.Closure
  http://dobrokot.nm.ru/cpp/CppMethodsCallback.html

- Указатели на функции-члены и реализация самых быстрых делегатов на С++.
  http://www.rsdn.ru/article/cpp/fastdelegate.xml
  http://www.codeproject.com/cpp/FastDelegate.asp

- Как сделать callback метод? Почему я не могу присвоить метод указателю на функцию?
  http://www.gamedev.ru/faq/?id=34

- boost::bind
  http://www.boost.org/doc/libs/1_41_0/libs/bind/bind.html  

- boost::function
  http://www.boost.org/doc/libs/1_41_0/doc/html/function.html
  http://sources.ru/wiki/doku.php?id=doc:cpp:boost:function
  http://forum.sources.ru/index.php?showtopic=215446

- Better way to call member function using function pointer?
  http://visualcpp.lite-programa.ru/?news=3901

- The Function Pointer Tutorials
  http://www.newty.de/fpt/callback.html  

- Указатели на функцию, коллбэки и функторы
  http://alenacpp.blogspot.com/2007/04/blog-post.html

- Использование функции-члена в качестве аргумента
  http://forums.realcoding.net/index.php?sho...amp;#entry35304

- Передача указателя на функцию-член одного класса в функцию другого класса, ...
  http://forum.sources.ru/index.php?showtopi...mp;view=showall

- Указатели на компоненты класса. Доступ по указателю
  http://www.citforum.ru/programming/cpp_march/cpp_082.shtml

- Указатель на функцию класса 
  http://www.sql.ru/Forum/actualthread.aspx?tid=713636
  http://forum.shelek.ru/index.php/topic,5088.0.html
  http://www.parashift.com/c++-faq-lite/poin...to-members.html
  http://www.rsdn.ru/forum/cpp/1656623.flat.aspx#1656623
  http://forum.sources.ru/index.php?showtopi...mp;view=showall
  http://forum.vingrad.ru/forum/topic-159810.html
  http://www.intuit.ru/department/pl/plintro/11/2.html
  http://forum.codenet.ru/showthread.php?t=40087
  http://www.interface.ru/home.asp?artId=8221
  http://netcode.ru/cpp/?lang=&katID=6&a...4&artID=571
  http://forum.sources.ru/index.php?showtopic=60397
  http://forum.sources.ru/index.php?showtopic=70190
  http://forum.sources.ru/index.php?showtopic=38247
  http://forum.sources.ru/index.php?showtopic=51174
  http://forum.sources.ru/index.php?showtopic=45336
  http://www.sources.ru/cpp/faqs/90.htm
  http://www.gamedev.ru/tip/?id=62
  http://leprecon.pisem.net/faq_213.htm
  http://forum.shelek.ru/index.php/topic,3979.0.html
 http://www.partow.net/programming/template...back/index.html


Это сообщение отредактировал(а) Alca - 5.7.2010, 14:19


--------------------
PM WWW ICQ Skype Jabber   Вверх
xvr
Дата 15.12.2009, 12:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(Alca @ 14.12.2009,  15:44)
Код

boost::function<void (CXThreadPool*)> f;
f = &CXThreadPool::_vOnTest;
///f(this);
_m_vecpthWorkThreads.at(_m_uiCurrTask)->_vOnExit  =  f ;   

Код

Error    1    error C2440: '=' : cannot convert from 'boost::function<Signature>' to 'void (__cdecl *)(void)'

 smile

_vOnExit тоже должен быть типа boost::function<void (CXThreadPool*)>, разве не очевидно?  smile 
PM MAIL   Вверх
Alca
Дата 15.12.2009, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата

разве не очевидно

xvr, спасибо. C бустом в лоб не сталкивался, поэтому знаниния в этой области поверхностные.
Теперь буду знать.


--------------------
PM WWW ICQ Skype Jabber   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0827 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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