在boost :: spawn中捕获指针

时间:2018-10-04 19:07:15

标签: c++ boost-asio

我有一个基类A,它具有工厂方法来创建派生类BC的实例。 BC的{​​{1}}被覆盖。有start()会先调用do_work(),然后再调用getInstance()。现在start()中的labmda不会存储捕获此指针的实例。因此存在范围问题。如果我通过instance(boost :: shared_ptr)来显式启动,然后在lambda中捕获它,那么它将起作用。如何避免将实例传递给spawn()

start()

2 个答案:

答案 0 :(得分:3)

您应该使用enable_shared_from_this

Live On Coliru

#define BOOST_COROUTINES_NO_DEPRECATION_WARNING
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>

boost::asio::io_service io_service;

class A : public boost::enable_shared_from_this<A> {
  public:
    virtual void start() = 0;
    static boost::shared_ptr<A> getInstance();
};

class B : public A {
  public:
    void start() {
        auto self = shared_from_this();
        boost::asio::spawn(io_service, [self](boost::asio::yield_context /*yield*/) {
            // work
        });
    }

};

class C : public A {
  public:
    void start() {
        auto self = shared_from_this();
        boost::asio::spawn(io_service, [self](boost::asio::yield_context /*yield*/) {
            // work
        });
    }
};

/*static*/ boost::shared_ptr<A> A::getInstance() { return boost::shared_ptr<A>(new B()); }

void do_work() {
    auto object = A::getInstance(); // this returns boost::shared_ptr and it does not store that instance
    object->start();
}

int main() {
}

答案 1 :(得分:-1)

老实说,我不知道为什么编译器允许这样做。 start功能在A世界中不存在。

BC不会覆盖任何内容,除非它们的基类中有要重写的虚函数。将纯虚拟start添加到类A,然后用virtual装饰BC start函数。 然后这两个类将覆盖某些内容。我怀疑这会导致您期望的行为。

class A {
public:
  static boost::shared_ptr<A> getInstance() {
    return boost::shared_ptr<A>(new B());
  }
  virtual void start()=0;
};
class B : public A {
public:
  virtual void start() {
    // stuff specific to class B
  }
};
class C : public A {
public:
  virtual void start() {
    // stuff specific to class C
  }
};