移动构造函数是否无效 shared_from_this
does the move constructor invalidate shared_from_this
我想用 class 开始一个线程,其中包含不可复制的成员。为了与线程通信,我想在将对象移入线程之前从该对象创建一个共享指针。
移动构造函数是否使共享指针无效?如果是这样,那么优雅的 c++ 方法是什么?一种解决方案是将 MessageClient 包装到一个共享指针中,但这会绕过移动构造函数。
class MessageClient : public std::enable_shared_from_this<MessageClient> {
private:
boost::asio::io_context io_context;
void send() {
// code
}
void operator() () {
// code
}
};
int main () {
MessageClient client;
auto pclient = client.shared_from_this();
std::thread thread(std::move(client));
pclient->send(); // terminate called after throwing an instance of 'std::bad_weak_ptr'
// what(): bad_weak_ptr
// Aborted (core dumped)
thread.join();
}
编辑
我得到了答案。我现在明白我错误地使用了 enable_shared_from_this
,但真正的答案是,没有办法解决不涉及将对象包装到另一个对象中的问题,例如智能指针或 lambda 函数(这是将对象包装到函子中)。我个人觉得第二种解决方案更简单,这就是我选择它的原因。
MessageClient client;
std::thread thread([&client](){client.run();});
client.send();
EDIT2
我找到了一个更明显的解决方案。如果我从对象创建一个引用,我不必包装它:
MessageClient client;
std::thread thread(std::ref(client));
client.send();
在 main
中,您可以创建 shared_ptr
的两个实例,它们共享同一个 MessageClient
对象。一个共享指针可以移动到线程体中,另一个留在主线程中,你可以用它与线程通信:
int main ()
{
std::shared_ptr<MessageClient> client = std::make_shared<MessageClient>();
std::shared_ptr<MessageClient> pclient = client;
std::thread thread(
[client = std::move(client)]()
{
(*client)(); // invoke body of thread
});
pclient->send(); // works fine
thread.join();
}
您使用 shared_from_this
的代码不起作用,因为当您确定至少有一个 [=] 实例时,shared_from_this
只能在 MessageClient
的成员函数内部调用12=] 管理 this
.
从 enable_shared_from_this
派生暗示 每个 实例都由某些 shared_ptr
拥有。您的问题是 client
不是,并且与将其移入线程无关。
您在此行有未定义的行为:
auto pclient = client.shared_from_this();
从一开始就使用 std::shared_ptr<MessageClient>
。
class MessageClient {
private:
boost::asio::io_context io_context;
void send() {
// code
}
void operator() () {
// code
}
};
int main () {
auto pclient = std::make_shared<MessageClient>();
std::thread thread([pclient]() { (*pclient)(); });
pclient->send();
thread.join();
}
我想用 class 开始一个线程,其中包含不可复制的成员。为了与线程通信,我想在将对象移入线程之前从该对象创建一个共享指针。
移动构造函数是否使共享指针无效?如果是这样,那么优雅的 c++ 方法是什么?一种解决方案是将 MessageClient 包装到一个共享指针中,但这会绕过移动构造函数。
class MessageClient : public std::enable_shared_from_this<MessageClient> {
private:
boost::asio::io_context io_context;
void send() {
// code
}
void operator() () {
// code
}
};
int main () {
MessageClient client;
auto pclient = client.shared_from_this();
std::thread thread(std::move(client));
pclient->send(); // terminate called after throwing an instance of 'std::bad_weak_ptr'
// what(): bad_weak_ptr
// Aborted (core dumped)
thread.join();
}
编辑
我得到了答案。我现在明白我错误地使用了 enable_shared_from_this
,但真正的答案是,没有办法解决不涉及将对象包装到另一个对象中的问题,例如智能指针或 lambda 函数(这是将对象包装到函子中)。我个人觉得第二种解决方案更简单,这就是我选择它的原因。
MessageClient client;
std::thread thread([&client](){client.run();});
client.send();
EDIT2
我找到了一个更明显的解决方案。如果我从对象创建一个引用,我不必包装它:
MessageClient client;
std::thread thread(std::ref(client));
client.send();
在 main
中,您可以创建 shared_ptr
的两个实例,它们共享同一个 MessageClient
对象。一个共享指针可以移动到线程体中,另一个留在主线程中,你可以用它与线程通信:
int main ()
{
std::shared_ptr<MessageClient> client = std::make_shared<MessageClient>();
std::shared_ptr<MessageClient> pclient = client;
std::thread thread(
[client = std::move(client)]()
{
(*client)(); // invoke body of thread
});
pclient->send(); // works fine
thread.join();
}
您使用 shared_from_this
的代码不起作用,因为当您确定至少有一个 [=] 实例时,shared_from_this
只能在 MessageClient
的成员函数内部调用12=] 管理 this
.
从 enable_shared_from_this
派生暗示 每个 实例都由某些 shared_ptr
拥有。您的问题是 client
不是,并且与将其移入线程无关。
您在此行有未定义的行为:
auto pclient = client.shared_from_this();
从一开始就使用 std::shared_ptr<MessageClient>
。
class MessageClient {
private:
boost::asio::io_context io_context;
void send() {
// code
}
void operator() () {
// code
}
};
int main () {
auto pclient = std::make_shared<MessageClient>();
std::thread thread([pclient]() { (*pclient)(); });
pclient->send();
thread.join();
}