【发布时间】:2017-08-29 10:55:40
【问题描述】:
如何在对象中运行线程时正确使用移动语义?
示例:
#include <iostream>
#include <thread>
#include <vector>
struct A {
std::string v_;
std::thread t_;
void start() {
t_ = std::thread(&A::threadProc, this);
}
void threadProc() {
for(;;) {
std::cout << "foo-" << v_ << '\n';
std::this_thread::sleep_for(std::chrono::seconds(5));
}
}
};
int main() {
A m;
{
A a;
a.v_ = "bar";
a.start();
m = std::move(a);
}
std::cout << "v_ = " << m.v_ << '\n'; /* stdout is 'v_ = bar' as expected */
/* but v_ in thread proc was destroyed */
/* stdout in thread proc is 'foo-' */
m.t_.join();
return 0;
}
我想在移动后使用类成员,但是当我离开作用域时,类成员被破坏并且 std::thread 按预期移动到新对象中,但它开始使用被破坏的成员。
在我看来是因为在线程初始化中使用了this 指针。
在这种情况下,最佳做法是什么?
【问题讨论】:
-
为了完整起见,还应定义构造函数、析构函数和复制构造函数。而在这种情况下应该显式删除复制构造函数。
-
嗯,不知道你能做些什么。你能重新审视一下这个要求吗?
-
它不使用默认的ctors吗?无论如何,我有更大的样本,在 ctors 和 dtor 中具有调试输出,并且行为者是相同的。
-
@FrankSchmid:不;不要定义无意义的方法。
-
线程正在执行
A的成员函数。由于A的前一个实例在移动后被破坏,线程使用的成员指针变得无效。您可以使用第二个独立对象实例,例如B(即 A 的成员)包含要执行的函数并将其移动到新的A实例。
标签: c++