Re: Вызов коллбэка-члена класса из другого класса
От: placement_new  
Дата: 22.01.09 10:10
Оценка:
Здравствуйте, aalp, Вы писали:

A>Здравствуйте,


A>Проблема: хочу вызвать член одного класса через указатель в другом классе, не прибегая к передаче в последний объекта первого.


A>Пытаюсь реализовать вызов члена контроллера из вьюхи, однако столкнулся с проблемой. Насколько я понял, для вызова из одного класса члена другого необходимо иметь инстанс класса, которому принадлежит вызываемый метод. Можно ли как-то этого избежать? В данном случае, хотелось бы, что бы вьюха ничего не знала про контроллер (кроме типа хэндлера, без этого не типизировать коллбэк).


A>Или есть более грамотный способ реализовать данное поведение? Использовать в качестве коллбэка дружественную функцию или статический член — не вариант.


A>
A>class Controller;
A>class IView;
A>class View;

A>typedef void(Controller::* OnEventHandler)();

A>struct IView
A>{
A>    virtual void Exec() = 0;
A>    virtual void SetHandler(OnEventHandler) = 0;
A>};

A>struct Controller
A>{
A>public:
A>    Controller(IView* pView)
A>    {
A>        pView->SetHandler(&Controller::Handler);
A>    }

A>    void Handler()
A>    {
A>        std::cout << "Handler from Controller called" << std::endl;
A>    }
A>};

A>struct View : public IView
A>{
A>    OnEventHandler  handler;

A>    virtual void SetHandler(OnEventHandler callback)
A>    {
A>        handler = callback;
A>    }

A>    virtual void Exec()
A>    {
A>        if(handler)
A>        {
A>            std::cout << "Handler exist, calling: ";
A>            handler();
A>        }
A>        else
A>        {
A>            std::cout << "Handler does not exist" << std::endl;
A>        }
A>    }
A>};

A>int main()
A>{
A>    IView* view = new View();
A>    Controller c(view);
    view->>Exec();
A>}

A>


Заведи в Controller поле boost::function<...>, в main установи его посредством View, и вызывай когда надо.
Или посмотри в строну boost::signal, тоже самое в принципе.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.