我正在尝试理解何时将该仿函数传递给()
时调用仿函数(即具有thread
运算符的类)的解构函数。但是在下面的例子中,构造函数被调用一次,但解构函数被调用了三次?
根据
run()
并在~run()
中将其关闭,调用它三次会导致问题。示例:
#include <iostream>
#include <thread>
using namespace std;
class run {
public:
run() { cout << "in run()" << endl; }
~run() { cout << "in ~run()" << endl; }
void operator()() {};
};
int main() {
run thread_r;
thread t(thread_r);
t.join();
}
提供输出:
in run()
in ~run()
in ~run()
in ~run()
答案 0 :(得分:5)
规则5,3和零。
如果定义析构函数,编译器仍将生成默认的复制构造函数和赋值运算符。
不幸的是,如果您定义了析构函数,则意味着您对资源释放有一些特殊处理,因此默认的复制和赋值代码将是完全错误的。
这是一个好的做法,我的意思是&#34;总是这样做,没有借口&#34;,至少提供复制构造函数和赋值运算符,即使你删除它们。
如果您打算提供这些服务,您也可以继续编写正确的移动运营商。
#include <iostream>
#include <thread>
using namespace std;
class run {
public:
run() { cout << "in run()" << endl; }
run(const run&) { cout << "copied()" << endl; }
run(run&&) { cout << "moved()" << endl; }
run& operator=(const run&) { cout << "copy-assigned()" << endl; return *this; }
run& operator=(run &&) { cout << "move-assigned()" << endl; return *this; }
~run() { cout << "in ~run()" << endl; }
void operator()() {};
};
int main() {
run thread_r;
thread t(thread_r);
t.join();
}
示例输出:
in run()
copied()
moved()
in ~run()
in ~run()
in ~run()
这是一个更新版本,以帮助解释构造函数和析构函数中发生的事情:
#include <iostream>
#include <thread>
#include <vector>
using namespace std;
class run {
public:
run()
: lifetime("constructed")
{
cout << lifetime << endl;
}
run(const run& other)
: lifetime("copied from " + other.lifetime)
{
cout << lifetime << endl;
}
run(run&& other)
: lifetime("move-constructed from " + other.lifetime)
{
other.lifetime = "[zombie] - " + other.lifetime;
cout << lifetime << endl;
}
run& operator=(const run& other)
{
lifetime = "copy assigned from " + other.lifetime + ", was once " + lifetime;
cout << lifetime << endl;
return *this;
}
run& operator=(run &&other)
{
lifetime = "move-assigned from " + other.lifetime + ", was once " + lifetime;
other.lifetime = "[zombie] - " + other.lifetime;
cout << lifetime << endl;
return *this;
}
~run()
{
lifetime = "lifetime ending: " + lifetime;
cout << lifetime << endl;
}
void operator()() {};
std::string lifetime;
};
int main() {
run thread_r;
thread t(thread_r);
t.join();
}
示例输出:
constructed
copied from constructed
move-constructed from copied from constructed
lifetime ending: [zombie] - copied from constructed
lifetime ending: move-constructed from copied from constructed
lifetime ending: constructed
对于任何不确定复制构造函数和移动构造函数的确切行为的人来说,最好在调试器中使用此代码,直到它变得清晰。