В c ++ есть какие-либо события / делегаты / интерфейсы / уведомления! что-нибудь? - PullRequest
7 голосов
/ 13 июня 2010

Скажем, у меня есть эти классы ViewA и ViewB

В цели C, используя шаблон делегата, я мог бы сделать

@protocol ViewBDelegate{

- (void) doSomething();
}

, затем в интерфейсе ViewB:

id<ViewBDelegate> delegate;

затем в реализации ViewA я установил делегат:

viewB.delegate = self;

и теперь я могу вызвать doSomething из viewB на любой делегат этого неизвестного типа.

[delegate doSomething];

"C ++ How to Program" имеетбыло хуже читать, я не могу найти простых примеров, которые демонстрируют базовые шаблоны проектирования.

То, что я ищу в C ++, это:

  • события ActionScriptи java
  • или делегаты или NSNotification в Objective C

все, что позволяет классу A, классу B и классу C знать, что ClassX didSomething () !!!

спасибо

Ответы [ 7 ]

9 голосов
/ 13 июня 2010

На вашем месте я бы не использовал указатели функций для выполнения этой задачи. Оставьте эту опцию гуру;)

В Boost есть красивая библиотека, которая называется сигналов . Это делает вашу жизнь проще! Это пример использования:

#include <iostream>
#include <boost/bind.hpp>
#include <boost/signal.hpp>
using namespace std;
using namespace boost;

struct A
{   void A_action() { cout << "A::A_action();" << endl; }   };
struct B
{   void B_action() { cout << "B::B_action();" << endl; }   };
struct C
{   void C_action() { cout << "C::C_action();" << endl; }   };
struct X
{
    // Put all the functions you want to notify!
    signal<void()> list_of_actions;
    void do_something()
    {
        std::cout << "Hello I am X!" << endl;
        list_of_actions(); // send notifications to all functions in the list!
    }
};
int main()
{
    X x;
    A a;
    B b;
    C c;
    x.list_of_actions.connect(bind(&A::A_action, a));
    x.list_of_actions.connect(bind(&B::B_action, b));
    x.list_of_actions.connect(bind(&C::C_action, c));
    x.do_something();
}

Будет напечатано:

Hello I am X!
A::A_action();
B::B_action();
C::C_action();

Вот как это работает.

Сначала вы объявляете место, в котором находятся делегаты:

signal<void()> list_of_actions;

Затем вы «подключаете» его к любой группе функций / функторов / вызываемых объектов, которые вы хотите вызвать.

x.list_of_actions.connect(bind(&A::A_action, a));
x.list_of_actions.connect(bind(&B::B_action, b));
x.list_of_actions.connect(bind(&C::C_action, c));

Обратите внимание, что я использовал bind. Итак, тип функций в list_of_actions одинаков, но мы можем подключить его к разным типам классов. Итак:

bind(&A::A_action, a)

Эта вещь производит вызываемую вещь типа void (), как мы объявили тип list_of actions ранее. Конечно, вы указываете экземпляр, к которому хотите применить эту функцию-член, во втором параметре ..

Если вы занимаетесь многопоточными вещами, используйте сестру сигналов2 .

Надеюсь, это поможет.

5 голосов
/ 13 июня 2010

все, что позволяет классу A, классу B и классу C знать, что ClassX didSomething () !!!

Возможно, вы ищете сигналов и слотов , который имеет несколько реализаций:

Я уверен, что естьбольше, но это наиболее значимые из которых я знаю.

2 голосов
/ 13 июня 2010

Лично мне нравится Невозможно быстрые делегаты C ++ от Сергей Рязанов. Очень аккуратная и простая в использовании реализация, заявленная как более быстрая, чем Boost::function.

Вы также можете найти события, реализованные там. Я не использую их, однако. Я реализовал свою собственную обработку событий, используя стиль .NET (отправитель, аргументы).

2 голосов
/ 13 июня 2010

Нет делегатов / событий / и т. Д.

Вы можете смоделировать интерфейсы, используя чисто виртуальные функции, см. здесь для аналогичного вопроса.

И есть указатели на функции ...

Таким образом, в основном ответ на ваш вопрос - нет, в C ++ этого нет (не знаю о последнем стандарте), но есть заменители иобходные ..

1 голос
/ 13 июня 2010

"Как программировать на C ++" читал хуже, и не могу найти простых примеров, демонстрирующих базовые шаблоны проектирования

Я думаю, что оригинальная книга "Шаблоны проектирования" содержит примеры того, как реализовать каждый шаблон с использованием C ++.

1 голос
/ 13 июня 2010

Все, что я знаю, есть метод, называемый call-back метод (Фактически, указатель на функцию ).

Делегирование?Это просто своего рода метод обратного вызова, и выглядит продвинутым

1 голос
/ 13 июня 2010

Ни в языке C ++, ни в связанной с ним стандартной библиотеке нет делегатов или событий. Конечно, есть много библиотек, которые реализуют такие вещи, или вы можете реализовать их самостоятельно.

...