C++ boost 回调返回数据

问题描述 投票:0回答:1

我正在努力研究从回调中获取数据的语法(不向回调发送参数)。我可以在没有数据的情况下触发回调,但希望对我所缺少的内容提供一些指导。如所列,它可以在不返回数据的情况下工作,请交换我尝试返回数据的相邻注释行(因此可能存在错误)。

#include <iostream>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/asio.hpp>
#include <map>
#include <string>

typedef boost::function<void()> callback;       
//typedef boost::function<void(std::string)> callback;    // With return argument

class B
{
public:
    //typedef boost::shared_ptr<const printer> SharedConst;

    B(boost::asio::io_service& io, std::string name_, int target_, callback call_)
    : timer_(io, boost::posix_time::seconds(1)),
      count(1), target(target_), name(name_), call(call_)
    {
        timer_.async_wait(boost::bind(&B::print, this));
    }
    
    ~B()
    {
        std::cout << "Final count is " << count << "\n";
    }
 
    void print()
    {
        if (count < target)
        {
            std::cout << name << " : " << count << "\n";
            ++count;

            timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds(1));
            timer_.async_wait(boost::bind(&B::print, this));
        } 
        else {
            call();
            //call(name);
        }
    }

private:
    callback call;
    boost::asio::deadline_timer timer_;
    int count;
    int target;
    std::string name;
};

class A {
private:
    std::map<std::string, B*> jobs;
    boost::asio::io_service io;

public:
    void acceptResult()
    //void acceptResult(std::string jobID_)
    {
        std::cout << "acceptResult" << std::endl; 
        //std::cout << "acceptResult from job : " << jobID_<< std::endl; 
        //free(jobs.at(jobID_));   
        //auto it = jobs.find(jobID_);
        //jobs.erase(it);
    }

    void newJob(std::string jobID_, unsigned int target)
    {
        B *b = new B(io, jobID_, target, boost::bind(&A::acceptResult, this));
        jobs.insert({jobID_, b});
    }

    void run()
    {
        io.run();
    }
};

int main()
{
    A a;
    a.newJob("j1", 5);
    a.newJob("j2", 3);

    a.run();

    return 0;
}

输出(不返回值):

j1 : 1
j2 : 1
j1 : 2
j2 : 2
j1 : 3
acceptResult
j1 : 4
acceptResult

预先感谢,保罗。

c++ boost callback
1个回答
0
投票

首先,让我们解决一些问题:

  • 初始化顺序(
    callback
    之后
    name
  • 内存泄漏(
    jobs
    应该管理作业生命周期):
  • 销毁命令(
    io
    应该在
    jobs
    之后)

我可能修复了更多,但我忘记了:Live On Coliru

j1 : 1
j2 : 1
j1 : 2
j2 : 2
j1 : 3
acceptResult
j1 : 4
acceptResult
Final count is 3
Final count is 5

问题

取消注释“问题”行,我注意到您忘记了

bind
name
参数的占位符:

boost::bind(&A::acceptResult, this, boost::placeholders::_1)

仅此而已!由于我选择了

unique_ptr
,所以不需要复杂的(而且不是异常安全的)舞蹈。哦,更不用说
free
new
/
delete
不正确!

void acceptResult(std::string jobID_) {
    std::cout << "acceptResult from job : " << jobID_<< std::endl;
    jobs.erase(jobID_);
}

住在Coliru

#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <iostream>
#include <map>
#include <string>

using callback = std::function<void(std::string)>; // With return argument

class B {
  public:
    B(boost::asio::io_service& io, std::string name_, int target_, callback call_)
        : timer_(io, boost::posix_time::seconds(1))
        , count(1)
        , target(target_)
        , name(name_)
        , call(call_) {
        timer_.async_wait(boost::bind(&B::print, this));
    }

    ~B() { std::cout << "Final count is " << count << "\n"; }

    void print() {
        if (count < target) {
            std::cout << name << " : " << count << "\n";
            ++count;

            timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds(1));
            timer_.async_wait(boost::bind(&B::print, this));
        } else {
             call(name);
        }
    }

  private:
    boost::asio::deadline_timer timer_;
    int                         count;
    int                         target;
    std::string                 name;
    callback                    call;
};

class A {
  private:
    boost::asio::io_service                   io; // ORDER! destruct last
    std::map<std::string, std::unique_ptr<B>> jobs;

  public:
    void acceptResult(std::string jobID_) {
        std::cout << "acceptResult from job : " << jobID_<< std::endl;
        jobs.erase(jobID_);
    }

    void newJob(std::string jobID_, unsigned int target) {
        jobs.emplace(jobID_,
                     std::make_unique<B>(io, jobID_, target,
                                         boost::bind(&A::acceptResult, this, boost::placeholders::_1)));
    }

    void run() { io.run(); }
};

int main() {
    A a;
    a.newJob("j1", 5);
    a.newJob("j2", 3);

    a.run();
}

打印

j1 : 1
j2 : 1
j1 : 2
j2 : 2
j1 : 3
acceptResult from job : j2
Final count is 3
j1 : 4
acceptResult from job : j1
Final count is 5
© www.soinside.com 2019 - 2024. All rights reserved.