关于 std::thread class 的问题
Questions about std::thread class
考虑以下 class header:
class ThreadClass {
public:
ThreadClass();
~ThreadClass();
void operator()(int val);
void set(int val);
int get();
private:
int x;
};
以及以下实现:
ThreadClass::ThreadClass(): x(0) {
std::cout << "Constructing..." << std::endl;
}
ThreadClass::~ThreadClass() {
std::cout << "Destructing..." << std::endl;
}
void ThreadClass::operator()(int val) {
set(val);
std::cout << get() << std::endl;
set(val * 2);
std::cout << get() << std::endl;
}
void ThreadClass::set(int val) {
x = val;
}
int ThreadClass::get() {
return x;
}
启动以下 main
,class 析构函数被调用多次而不是一次:
int main(int argc, char const *argv[]) {
std::thread x = std::thread(ThreadClass(), 10);
x.join();
return 0;
}
>>> Constructing...
>>> Destructing...
>>> Destructing...
>>> 10
>>> 20
>>> Destructing...
由于我对std::thread
class的了解不是很深,想请教各位:
- 为什么会这样?真诚的,我只期待
ThreadClass
. 的一个实例
- 为了避免意外行为,是否有必要重载某些 class 运算符?
您正在调用您尚未定义(但已为您创建)的隐式构造函数。你可以在这里看到他们的行动:
#include <thread>
#include <iostream>
class ThreadClass {
public:
ThreadClass() {
std::cout << "Constructing..." << std::endl;
}
ThreadClass(const ThreadClass& t) {
std::cout << "Copy constructing..." << std::endl;
this->x = t.x;
}
// ThreadClass(ThreadClass&& t) {
// std::cout << "Move constructing..." << std::endl;
// this->x = t.x;
// }
~ThreadClass() {
std::cout << "Destructing..." << std::endl;
}
void operator()(int val) {
set(val);
std::cout << get() << std::endl;
set(val * 2);
std::cout << get() << std::endl;
}
void set(int val) {
x = val;
}
int get() {
return x;
}
private:
int x;
};
int main(int argc, char const *argv[]) {
std::thread x = std::thread(ThreadClass(), 10);
x.join();
return 0;
}
输出:
Constructing...
Copy constructing...
Copy constructing...
Destructing...
Destructing...
10
20
Destructing...
如果您还想看到它的实际效果,您可以取消注释移动构造函数。
直接回答您的问题:
why this happens? Sincerely, I was expecting just a single instance of the ThreadClass.
发生这种情况是因为您正在传递一个对象,因此 post 中提到的其他构造函数被多次调用。
In order to avoid unexpected behaviour, is it necessary to overload some of the class operators?
意外行为是什么意思?这完全符合 C++ 的意图。这是 C++ 明确定义的行为。
考虑以下 class header:
class ThreadClass {
public:
ThreadClass();
~ThreadClass();
void operator()(int val);
void set(int val);
int get();
private:
int x;
};
以及以下实现:
ThreadClass::ThreadClass(): x(0) {
std::cout << "Constructing..." << std::endl;
}
ThreadClass::~ThreadClass() {
std::cout << "Destructing..." << std::endl;
}
void ThreadClass::operator()(int val) {
set(val);
std::cout << get() << std::endl;
set(val * 2);
std::cout << get() << std::endl;
}
void ThreadClass::set(int val) {
x = val;
}
int ThreadClass::get() {
return x;
}
启动以下 main
,class 析构函数被调用多次而不是一次:
int main(int argc, char const *argv[]) {
std::thread x = std::thread(ThreadClass(), 10);
x.join();
return 0;
}
>>> Constructing...
>>> Destructing...
>>> Destructing...
>>> 10
>>> 20
>>> Destructing...
由于我对std::thread
class的了解不是很深,想请教各位:
- 为什么会这样?真诚的,我只期待
ThreadClass
. 的一个实例
- 为了避免意外行为,是否有必要重载某些 class 运算符?
您正在调用您尚未定义(但已为您创建)的隐式构造函数。你可以在这里看到他们的行动:
#include <thread>
#include <iostream>
class ThreadClass {
public:
ThreadClass() {
std::cout << "Constructing..." << std::endl;
}
ThreadClass(const ThreadClass& t) {
std::cout << "Copy constructing..." << std::endl;
this->x = t.x;
}
// ThreadClass(ThreadClass&& t) {
// std::cout << "Move constructing..." << std::endl;
// this->x = t.x;
// }
~ThreadClass() {
std::cout << "Destructing..." << std::endl;
}
void operator()(int val) {
set(val);
std::cout << get() << std::endl;
set(val * 2);
std::cout << get() << std::endl;
}
void set(int val) {
x = val;
}
int get() {
return x;
}
private:
int x;
};
int main(int argc, char const *argv[]) {
std::thread x = std::thread(ThreadClass(), 10);
x.join();
return 0;
}
输出:
Constructing...
Copy constructing...
Copy constructing...
Destructing...
Destructing...
10
20
Destructing...
如果您还想看到它的实际效果,您可以取消注释移动构造函数。
直接回答您的问题:
why this happens? Sincerely, I was expecting just a single instance of the ThreadClass.
发生这种情况是因为您正在传递一个对象,因此 post 中提到的其他构造函数被多次调用。
In order to avoid unexpected behaviour, is it necessary to overload some of the class operators?
意外行为是什么意思?这完全符合 C++ 的意图。这是 C++ 明确定义的行为。