在 boost::spawn 内捕获指针
capturing pointer inside boost::spawn
我有基础 class A,它有工厂方法来创建派生 classes B
和 C
的实例。 B
和 C
已覆盖 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
世界中不存在。
类 B
和 C
没有覆盖任何东西,除非它们的基础 class 中有一个虚函数可以覆盖。在classA中添加一个纯虚start
,然后用虚修饰B
和C
start
函数。 然后 那两个 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
:
#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() {
}
我有基础 class A,它有工厂方法来创建派生 classes B
和 C
的实例。 B
和 C
已覆盖 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
世界中不存在。
类 B
和 C
没有覆盖任何东西,除非它们的基础 class 中有一个虚函数可以覆盖。在classA中添加一个纯虚start
,然后用虚修饰B
和C
start
函数。 然后 那两个 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
:
#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() {
}