移动构造函数是否使shared_from_this无效
does the move constructor invalidate shared_from_this
我想用一个包含不可复制成员的类开始一个线程。为了与线程通信,我想在将对象移动到线程之前从对象创建一个共享指针。
移动构造函数是否使共享指针无效?如果是这样,优雅的 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();
编辑2
我找到了一个更明显的解决方案。如果我从对象创建引用,则不必包装它:
MessageClient client;
std::thread thread(std::ref(client));
client.send();
从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();
}
在main
中,您可以创建两个共享同一MessageClient
对象的shared_ptr
实例。一个共享的 ptr 可以移动到线程主体中,另一个保留在 main 中,您可以使用它与线程通信:
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
因为当您确定至少有一个shared_ptr
实例管理this
时MessageClient
的成员函数中才能调用它。
相关文章:
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 无法访问嵌套类.类的使用无效
- 如何解决"invalid conversion from 'char' to 'const char*'"
- 如果用户输入无效,如何使用字符串变量-C++重复输入命令
- 如何解决错误:SCIP C++中的 SCIP 阶段无效 <10>
- 在没有参数列表的情况下使用模板名称"Event"无效,模板问题
- FFMPEG配置文件级别id大小无效
- 错误:从"int"到枚举c++的转换无效
- 如何修复此错误:className::className的无效使用
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- C++-模板嵌套类的引用初始化无效
- 错误:无效的预处理指令 #i 的意思是 #if?
- 多维数组 C++ 中数组下标的类型"int[int]"无效
- 在 C++ 中使用正则表达式错误时出现问题 括号表达式中的范围无效
- 从 'int' 到 'int*' CPP 的转换无效
- 如何接受 [ENTER] 键作为无效输入并发送错误消息
- 由于无效的 ValidateRgn() 子窗口不会收到WM_PAINT消息
- C++ PTHREADS - 无效转换无效*(*)()到无效*(*)(无效*)
- 声明为无效的变量或字段'...' Ardunio 编译器上的错误
- 数组下标的类型"float*[float]"无效