在 boost::spawn 内捕获指针

capturing pointer inside boost::spawn

我有基础 class A,它有工厂方法来创建派生 classes BC 的实例。 BC 已覆盖 start()。有 do_work() 调用 getInstance(),然后调用 start()。现在spawn()里面的labmda不存储captures this指针的实例。所以存在范围问题。如果我通过 instance(boost::shared_ptr) 显式启动然后在 lambda 中捕获它,那么它就可以工作。如何避免将实例传递给 start()

    class B : public A {
      public:
        void start(){
            boost::spawn(io_service, [this](boost::asio::yield_context yield) 
          {  
             // work
            });
         }

    }
    class C: public A {
         public: 
         void start(){
            boost::spawn(io_service, [this](boost::asio::yield_context yield) 
          {  
             // work
            });
         }
    }
    do_work() {
       auto object = A::getInstance(); // this returns boost::shared_ptr and it does not store that instance
       object->start();

    }

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

   }

老实说,我不知道编译器为什么让这个通过。 start 函数在 A 世界中不存在。

BC 没有覆盖任何东西,除非它们的基础 class 中有一个虚函数可以覆盖。在classA中添加一个纯虚start,然后用虚修饰BCstart函数。 然后 那两个 class 是否会覆盖某些内容。我怀疑这会导致您期望的行为。

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
  }
};

你应该使用 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() {
}