dnfpk001 发表于 2017-7-9 11:56:08

《C++Boost库asio》第三篇 怎么绑定成员函数(之前绑定的是自由函数):


怎么绑定成员函数(之前绑定的是自由函数):
1.bind方式(不推荐) 2. lambda(推荐)
async_wait(boost::bind(&printer::print, this));
bind参数:1。成员函数的地址形式 2。调用者

class printer {
public:
printer(boost::asio::io_service &io) : timer_(io, boost::posix_time::seconds(1)),

count_(0) {
   timer_.async_wait(boost::bind(&printer::print, this));
}
~printer() { std::cout << "Final count is " << count_ << std::endl; }

void print() {
    // ....do something ....
}

private:
boost::asio::deadline_timer timer_;
int count_;
};

int main() {
boost::asio::io_service io;
printer p(io);
io.run();
return 0;
}

如果是用STL的bind来绑定
#include <functional>//跟函数相关的都在这里头
把bind 改成 std::bind

如果是用lambda来绑定
不用引入头文件
改成 timer_.async_wait((const auto&){this->print();});
const auto&是函数自带的参数,boost::system::error_code,是一个错误码,用auto来替代的这种

方式,要求C++14以上版本才能编译

bind返回的是 function<void(const boost::system::error_code)>
lambda返回的是lambda
区别:
function是真正生成一个类的实体,有默认的回调,默认的赋值,操作等。。而且不能在编译器展

开,sizeof也相对要大
lambda可以在编译器展开,开销很小,效率高

避免:绑定的资源,在回调之前就已经失效了
比如这里的this,[]里的资源,timer_.async_wait({const auto&){this->print();});不能让

它在回调之前失效,比如让资源不失效?或者让正常析构的时候,把回调取消掉?先试试,在析构的

时候,调用timer_.cancel() 取消等待的回调,会出现的问题是:timer_在自身析构的过程中,也会

调用cancel的过程,而且如果回调函数中的参数有我自身,实际上已经没有任何意义了,在析构的时

候调用已经晚了,所以cancel没有用
不太正确但是安全的方式:
进行一次判断
timer_async_wait((const auto& error) {
if(error == boost::asio::error::operation_aborted) {
std::cout << "cancel now\n";//出现问题,这个地方不能调用this等资源
} else {
this -> print();
}
});


dnfpk001 发表于 2017-7-10 11:28:43

怎么绑定成员函数(之前绑定的是自由函数):

1.bind方式(不推荐)

#include <iostream>
#include <boost\asio.hpp>
#include <boost\bind.hpp>
#include <boost\date_time\posix_time\posix_time.hpp>

class printer {
public:
        printer(boost::asio::io_service &io) :
                timer_(io, boost::posix_time::seconds(1)),
                count_(0)
        {
                timer_.async_wait(boost::bind(&printer::print, this));
        }

        ~printer() {
                std::cout << "Final count is " << count_ << std::endl;
        }

        void print() {
                // ...d0 something ...
                std::cout << "in print ..." << std::endl;
        }

private:
        boost::asio::deadline_timer timer_;
        int count_;
};

int main()
{
        // 我们的程序和操作系统底层之间的一个相互传递的枢纽
        // 会把事件按照一定方式进行处理;
        boost::asio::io_service io;

        printer p(io);

        // 开始运行;
        io.run();

        std::cout << "mian finish run \n" << std::endl;// 提示下main函数已经结束了
        system("pause");// 让VS控制台程序不会一闪而过;
    return 0;
}

如果是用STL的bind来绑定
#include <functional>//跟函数相关的都在这里头
把bind 改成 std::bind

2. lambda(推荐)

如果是用lambda来绑定
不用引入头文件
改成 timer_.async_wait((const auto&){this->print();});
const auto&是函数自带的参数,boost::system::error_code,是一个错误码,用auto来替代的这种方式,要求C++14以上版本才能编译

#include <iostream>
#include <boost\asio.hpp>
#include <boost\date_time\posix_time\posix_time.hpp>

class printer {
public:
        printer(boost::asio::io_service &io) :
                timer_(io, boost::posix_time::seconds(1)),
                count_(0)
        {
                timer_.async_wait((const boost::system::error_code&) {this->print();});
        }

        ~printer() {
                std::cout << "Final count is " << count_ << std::endl;
        }

        void print() {
                // ...d0 something ...
                std::cout << "in print ..." << std::endl;
        }

private:
        boost::asio::deadline_timer timer_;
        int count_;
};

int main()
{
        // 我们的程序和操作系统底层之间的一个相互传递的枢纽
        // 会把事件按照一定方式进行处理;
        boost::asio::io_service io;

        printer p(io);

        // 开始运行;
        io.run();

        std::cout << "mian finish run \n" << std::endl;// 提示下main函数已经结束了
        system("pause");// 让VS控制台程序不会一闪而过;
    return 0;
}



bind返回的是 function<void(const boost::system::error_code)>
lambda返回的是lambda
区别:
function是真正生成一个类的实体,有默认的回调,默认的赋值,操作等。。而且不能在编译器展开,sizeof也相对要大
lambda可以在编译器展开,开销很小,效率高


避免:绑定的资源,在回调之前就已经失效了
比如这里的this,[]里的资源,timer_.async_wait({const auto&){this->print();});不能让

它在回调之前失效,比如让资源不失效?或者让正常析构的时候,把回调取消掉?先试试,在析构的

时候,调用timer_.cancel() 取消等待的回调,会出现的问题是:timer_在自身析构的过程中,也会

调用cancel的过程,而且如果回调函数中的参数有我自身,实际上已经没有任何意义了,在析构的时候调用已经晚了,所以cancel没有用
不太正确但是安全的方式:
进行一次判断

timer_async_wait((const auto& error) {
if(error == boost::asio::error::operation_aborted) {
std::cout << "cancel now\n";//出现问题,这个地方不能调用this等资源
} else {
this -> print();
}
});
页: [1]
查看完整版本: 《C++Boost库asio》第三篇 怎么绑定成员函数(之前绑定的是自由函数):