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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> класс-обертка, Help!!! 
:(
    Опции темы
Leksey
Дата 7.7.2005, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Нужно написать класс обертку(или группу классов),так чтобы он взаимодействал с любым другим его классом X и позолял запускать методы X в отдельном потоке,в своем потоке и т.п.
(Что-то намекали на шаблоны и очередь сообщений)
Честно говоря я в задании сам толком не разобрался.
Огромная просьба помочь либо ссылками на что-нибудь подобное,либо собственным опытом.А то я даже не знаю с чего начатьsmile.
PM MAIL   Вверх
Void
Дата 7.7.2005, 21:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

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



Сильно напоминает делегаты дотнета...
В принципе это лекго реализуется на boost::bind + boost::thread и работать будет примерно так (опуская сам класс-обертку):
Код

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

class MyClass {
    int data_;
public:
    MyClass(int data) : data_(data) { }
    void SomeMethod(int arg1, int arg2) {
        std::cout << (arg1 + arg2) * data_;
    }
};

int main(void) {
    MyClass C(2);
    boost::thread th(boost::bind(&MyClass::SomeMethod, &C, 3, 5));
    th.join();
/* Output:
16
*/
}


Если вам все нужно написать самостоятельно - это, имхо, очень большой геморрой. Но по любому исходники boost::bind тут в помощь, а уж вызов в отдельном потоке можно и самому.


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Leksey
Дата 7.7.2005, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Нужно все написать самомуsmile
К тому же должна быть возможность запуска как в отдельном потоке так и в текущем.
И еще не может ли кто-нибудь скинуть исходник boost::bind на мыло,а то 10м с моим инетом проблема.
Заранее thks.
PM MAIL   Вверх
Void
Дата 8.7.2005, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

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



Цитата(Leksey @ 8.7.2005, 00:05)
К тому же должна быть возможность запуска как в отдельном потоке так и в текущем.

Если в текущем, то, надеюсь, синхронно? Т.е. возврат к вызывающей стороне не происходит, пока вызыванный метод не завершился? Если не так, то геморрой существенно возрастает.
Цитата(Leksey @ 8.7.2005, 00:05)
И еще не может ли кто-нибудь скинуть исходник boost::bind на мыло,а то 10м с моим инетом проблема.

Это около 60 Кб (если вытягивать _все_ необходимые *.hpp из буста, то больше) кода. Довольно однородного, но все же... Ну что ж, пожалуйста.

Наверное, я слишком преувеличил сложность задачи, глядя на кроссплатформенную и ужасно универсальную реализацию boost::bind smile Вот несколько статей, думаю, кое-что полезное о том, как вызвать произвольный метод произвольного объекта вне контекста, из них извлечь можно:
http://rsdn.ru/article/cpp/delegates.xml
http://www.codeproject.com/cpp/NativeDelegates.asp (англ.)
http://www.codeproject.com/cpp/FastDelegate.asp (англ.)



--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Leksey
Дата 8.7.2005, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Спасибо большое Void и Rooslan S. Khayrov.

PM MAIL   Вверх
Void
Дата 9.7.2005, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

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



Цитата(Leksey @ 8.7.2005, 23:50)
Спасибо большое Void и Rooslan S. Khayrov.

Это одно и то же лицо smile

Вот реализация в первом приближении. Корявая и со множеством очевидных косяков, но рабочая. Понимает свободные функции и методы с числом параметров не более двух.
За реализацию класса Thread просьба сильно не пинать, так как с MT я практически не работал.
Код

// delegates.hpp

#ifndef BICYCLE_DELEGATES_HPP_INCLUDED
#define BICYCLE_DELEGATES_HPP_INCLUDED

struct DelegateBase
{
    virtual void invoke() = 0;
};

template <class TRet>
class StaticDelegate0 : public DelegateBase
{
    typedef TRet (*func_t)(void);
    func_t func_;
public:
    StaticDelegate0(func_t func) : func_(func) { }
    void invoke()
    {
        (*func_)();
    }
};

template <class TRet>
DelegateBase *make_delegate(TRet (*func)(void))
{
    return new StaticDelegate0<TRet>(func);
}

template <class TObj, class TRet>
class MemberDelegate0 : public DelegateBase
{
    typedef TRet (TObj::*mem_func_t)(void);
    mem_func_t mem_func_;
    TObj *pobj_;
public:
    MemberDelegate0(mem_func_t mem_func, TObj *pobj) :
      mem_func_(mem_func), pobj_(pobj) { }
    void invoke()
    {
        (pobj_->*mem_func_)();
    }
};

template <class TObj, class TRet>
DelegateBase *make_delegate(TRet (TObj::*mem_func)(void), TObj *pobj)
{
    return new MemberDelegate0<TObj, TRet>(mem_func, pobj);
}

template <class TRet, class TArg1>
class StaticDelegate1 : public DelegateBase
{
    typedef TRet (*func_t)(TArg1);
    func_t func_;
    TArg1 arg1_;
public:
    StaticDelegate1(func_t func, TArg1 arg1) : func_(func), arg1_(arg1) { }
    void invoke()
    {
        (*func_)(arg1_);
    }
};

template <class TRet, class TArg1>
DelegateBase *make_delegate(TRet (*func)(TArg1), TArg1 arg1)
{
    return new StaticDelegate1<TRet, TArg1>(func, arg1);
}

template <class TObj, class TRet, class TArg1>
class MemberDelegate1 : public DelegateBase
{
    typedef TRet (TObj::*mem_func_t)(TArg1);
    mem_func_t mem_func_;
    TObj *pobj_;
    TArg1 arg1_;
public:
    MemberDelegate1(mem_func_t mem_func, TObj *pobj, TArg1 arg1) :
      mem_func_(mem_func), pobj_(pobj), arg1_(arg1) { }
    void invoke()
    {
        (pobj_->*mem_func_)(arg1_);
    }
};

template <class TObj, class TRet, class TArg1>
DelegateBase *make_delegate(TRet (TObj::*mem_func)(TArg1), TObj *pobj, TArg1 arg1)
{
    return new MemberDelegate1<TObj, TRet, TArg1>(mem_func, pobj, arg1);
}

template <class TRet, class TArg1, class TArg2>
class StaticDelegate2 : public DelegateBase
{
    typedef TRet (*func_t)(TArg1, TArg2);
    func_t func_;
    TArg1 arg1_;
    TArg2 arg2_;
public:
    StaticDelegate2(func_t func, TArg1 arg1, TArg2 arg2) :
      func_(func), arg1_(arg1), arg2_(arg2) { }
    void invoke()
    {
        (*func_)(arg1_, arg2_);
    }
};

template <class TRet, class TArg1, class TArg2>
DelegateBase *make_delegate(TRet (*func)(TArg1, TArg2), TArg1 arg1, TArg2 arg2)
{
    return new StaticDelegate2<TRet, TArg1, TArg2>(func, arg1, arg2);
}

template <class TObj, class TRet, class TArg1, class TArg2>
class MemberDelegate2 : public DelegateBase
{
    typedef TRet (TObj::*mem_func_t)(TArg1, TArg2);
    mem_func_t mem_func_;
    TObj *pobj_;
    TArg1 arg1_;
    TArg2 arg2_;
public:
    MemberDelegate2(mem_func_t mem_func, TObj *pobj, TArg1 arg1, TArg2 arg2) :
      mem_func_(mem_func), pobj_(pobj), arg1_(arg1), arg2_(arg2) { }
    void invoke()
    {
        (pobj_->*mem_func_)(arg1_, arg2_);
    }
};


template <class TObj, class TRet, class TArg1, class TArg2>
DelegateBase *make_delegate(TRet (TObj::*mem_func)(TArg1, TArg2), TObj *pobj,
                            TArg1 arg1, TArg2 arg2)
{
    return new MemberDelegate2<TObj, TRet, TArg1, TArg2>(mem_func, pobj, arg1, arg2);
}

// simple delegate wrapper
// implements exclusive ownership semantics
class Delegate
{
    DelegateBase *target_;
    // non-copyable
    Delegate(const Delegate&);
    const Delegate &operator =(const Delegate&);
public:
    Delegate(DelegateBase *target) : target_(target) { }
    ~Delegate()
    {
        delete target_;
    }
    const Delegate &operator =(DelegateBase *target)
    {
        delete target_;
        target_ = target;
    }
    DelegateBase *get_target()
    {
        return target_;
    }
    void operator ()()
    {
        target_->invoke();
    }
};

#endif // BICYCLE_DELEGATES_HPP_INCLUDED

// thread.hpp

#ifndef BICYCLE_THREAD_HPP_INCLUDED
#define BICYCLE_THREAD_HPP_INCLUDED

#include <cstddef>

#include "delegates.hpp"

struct ThreadParam
{
    DelegateBase *delegate;
};

class Thread
{
    uintptr_t handle_;
    ThreadParam param_;
    // non-copyable
    Thread(const Thread&);
    const Thread &operator =(const Thread&);
public:
    Thread(Delegate &p);
    ~Thread();
    // returns thread handle
    uintptr_t get_handle()
    {
        return handle_;
    }
    // determines whether thread represented by *this has finished
    bool is_finished();
    // terminates thread represented by *this
    void terminate();
    // blocks current thread until function called in *this thread terminates
    void wait();
};

#endif // BICYCLE_THREAD_HPP_INCLUDED

// thread.cpp

#include "thread.hpp"

#include <stdexcept>
#include <process.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

void __cdecl thread_proxy(void *param)
{
    ThreadParam *p = static_cast<ThreadParam*>(param);
    p->delegate->invoke();
    _endthreadex(0);
}

Thread::Thread(Delegate &f)
{
    param_.delegate = f.get_target();
    handle_ = _beginthread(thread_proxy, 0, &param_);
    if (handle_ < 0)
        throw std::runtime_error("failed to create thread");
}

Thread::~Thread()
{
    CloseHandle(reinterpret_cast<HANDLE>(handle_));
}

bool Thread::is_finished()
{
    DWORD exitcode;
    GetExitCodeThread(reinterpret_cast<HANDLE>(handle_), &exitcode);
    return exitcode != STILL_ACTIVE;
}

void Thread::terminate()
{
    TerminateThread(reinterpret_cast<HANDLE>(handle_), 1);
}

void Thread::wait()
{
    WaitForSingleObject(reinterpret_cast<HANDLE>(handle_), INFINITE);
}

// delegates.cpp : usage example

#include <iostream>

#include "delegates.hpp"
#include "thread.hpp"

void bar(int arg)
{
    std::cout << "bar called: " << "arg = " << arg << std::endl;
}

class Foo
{
    int data_;
public:
    Foo(int data) : data_(data) { }
    void bar(int arg1, int arg2)
    {
        std::cout << "Foo::bar called: " <<
            "this->data_ = " << data_ <<
            ", arg1 = " << arg1 <<
            ", arg2 = " << arg2 << std::endl;
    }
};

int main(int argc, char* argv[])
{
    Delegate d1 = make_delegate(bar, 2);
    Foo c(3);
    Delegate d2 = make_delegate(&Foo::bar, &c, 5, 7);
    d1();
    d2();
    Thread t1(d1);
    t1.wait();
    Thread t2(d2);
    t2.wait();
    return 0;
}



--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0457 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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