Как можно активировать :: bind вызов частных методов?

18

boost :: bind чрезвычайно удобен в ряде ситуаций. Один из них - отправить / отправить вызов метода, чтобы io_service выполнил вызов позже, когда это возможно.

В таких ситуациях boost :: bind ведет себя так, как можно было бы искренне ожидать:

#include <boost/asio.hpp>
#include <boost/bind.hpp>

boost::asio::io_service ioService;

class A {
public:     A() {
                // ioService will call B, which is private, how?
                ioService.post(boost::bind(&A::B, this));
            } 
private:    void B() {}
};

void main()
{
    A::A();
    boost::asio::io_service::work work(ioService);
    ioService.run();
}

Однако, насколько я знаю, boost создает функтор (класс с operator () ()), способный вызвать данный метод на данном объекте. Должен ли этот класс иметь доступ к частному B? Наверное, нет.

Что мне здесь не хватает?

    
задан Gabriel 30.06.2011 в 18:40
источник

2 ответа

35

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

    
ответ дан Mike Seymour 30.06.2011 в 18:44
источник
  • То же самое верно для обычных указателей на частные статические методы. –  MSalters 01.07.2011 в 11:38
7

Своя сквозная функция-указатель-член, увеличивает вызовы частных функций. Функция-член класса создает указатель и передает его для повышения, а затем boost использует этот указатель для вызова частной функции для объекта класса.

Вот одна простая иллюстрация этой основной идеи:

class A;

typedef void (A::*pf)();

class A 
{
public:     
    pf get_ptr() { return &A::B; } //member function creates the pointer
private:    
    void B() { cout << "called private function" << endl; }
};

int main() {
        A a;
        pf f = a.get_ptr();
        (a.*f)();
        return 0;
}

Вывод:

  

называется частной функцией

Хотя он не использует boost, но основная идея - именно это.

Обратите внимание, что только функции-члены и friend могут создавать указатель на функцию private -члена. Другие не могут его создать.

Демо на идеоне: Ссылка

    
ответ дан Nawaz 30.06.2011 в 18:54
источник
  • Спасибо за образец кода! –  Gabriel 30.06.2011 в 19:14