2010-08-04 4 views
4

Я хочу добавить функцию регистрации в рабочий класс, как передать функцию-член как указатель на функцию? использовать mem_fun?как передать функцию-член как функцию указателя?

здесь пример кода:

class Work{ 
public: 
    void (*logger) (const string &s); 
    void do_sth(){if (logger) logger("on log")}; 
}; 

classs P{ 
public: 
    void log(const string &s)(cout << s); 
}; 

int main(){ 
    Work w; 
    P p; 
    w.logger = &p.log; 
    w.do_sth(); 
} 

редактировать:

Я не хочу использовать пустоту (P :: * ххх)(), потому что прилипают к классу Р ...

Я знаю, C++ скрыть STH, функция реального журнала: аннулируются журнал (P & р, сопз строка & s),

и реальный проект, как это:

Я создаю CDialog, и есть функция журнала, она копирует строку журнала в CEdit.

Так что мне нужно передать эту функцию журнала к классу Worker, этот класс сделать некоторые последовательного порта работу,

Мне нужно войти и показать данные и отправлять RECIVED ...

+0

Я думаю, что это очень общий шаблон дизайна. – linjunhalida

ответ

4

Вы можете сделать это с помощью std::function и std::bind:

#include <functional> 
#include <iostream> 
#include <string> 

class Work { 
public: 
    std::function<void(const std::string&)> logger; 
    void do_sth() { logger("on log"); } 
}; 

class P { 
public: 
    void log(const std::string& s) { std::cout << s; } 
}; 

int main() { 
    Work w; 
    P p; 
    w.logger = std::bind(&P::log, p, std::placeholders::_1); 
    w.do_sth(); 
} 

Заметьте, что function и bind не может быть в стандартной библиотеке вашей реализации пока; вы также можете get them from the Boost libraries.

+0

Да, это способ сделать эту работу. – linjunhalida

+0

@James McNellis, не следует «std :: placeholders :: _ 1' быть' std :: tr1 :: placeholders :: _ 1' вместо этого? – Praetorian

+0

В моем реальном проекте я использую (и скомпилировал ОК): using namespace std; device.logger = boost :: bind (& CDeviceTesterDlg :: logger, this, _1); – linjunhalida

1

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

0

Для этого потребуются замыкания, которые C++ точно не имеют. Вы можете создавать функторы и использовать шаблоны, но вам придется немного отвлечься.

+0

Да, функтор и закрытие должны работать, любая ссылка на пример? – linjunhalida

+0

@linjunhalida: Джеймс Макнеллис избил меня. Его ответ лучше. – zneak

Смежные вопросы