규칙 :
#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();
}
출력을 준다.
소멸자를 정의하면 컴파일러는 여전히 기본 복사 생성자 및 할당 연산자를 생성합니다.
불행히도 소멸자를 정의한 경우 리소스 할당 해제와 관련하여 특별한 처리가 필요하므로 기본 복사 및 할당 코드가 잘못 될 수 있습니다.
좋은 사례 인은 삭제하더라도 적어도 생성자와 할당 연산자를 제공하기 위해 항상 "변하지 않습니다."라는 의미입니다.
당신이 이것을 제공한다면 올바른 이동 연산자도 쓸 수 있습니다.
#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();
}
예 출력 :
#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
여기를
in run()
copied()
moved()
in ~run()
in ~run()
in ~run()
는 생성자와 소멸자에서 무슨 일이 일어나고 있는지 설명 할 수있는 업데이트 버전입니다 술을 마시지 않는 사람 복사 생성자와 이동 생성자의 정확한 동작에 관해서는 명확해질 때까지 디버거에서이 코드를 사용하는 것이 좋습니다.
'thread t (std :: ref (thread_r));'을 시도하십시오. [데모] (https://wandbox.org/permlink/3m7i49Zzs3fdikVX). –
@KerrekSB 경고 문구없이 위험 할 수 있습니다. 나는'thread t (std :: move (thread_r)); 또는'std :: thread t (run {});을 선호 할 것입니다. – sehe
@sehe 그래서 이동이 선호됩니까? functor가 리소스 (예 : 열린 파일)를 포함하고 있고 그것을 이동하고'~ run()'을 호출하는 것이 문제가있는 경우, 맞습니까? deconstructor를 호출하지 않고 리소스를 정렬 할 수있는 방법이 있습니까? – qweruiop