Reputation: 566
Considering the following class header:
class ThreadClass {
public:
ThreadClass();
~ThreadClass();
void operator()(int val);
void set(int val);
int get();
private:
int x;
};
And the following implementation:
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;
}
Launching the following main
, class destructor is called several times instead of one:
int main(int argc, char const *argv[]) {
std::thread x = std::thread(ThreadClass(), 10);
x.join();
return 0;
}
>>> Constructing...
>>> Destructing...
>>> Destructing...
>>> 10
>>> 20
>>> Destructing...
Since my knowledge about the std::thread
class is not so deep, I would like to ask you:
ThreadClass
.Upvotes: 1
Views: 62
Reputation: 3675
You are invoking implicit constructors that you haven't defined (yet have been made for you). You can see them in action here:
#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;
}
Output:
Constructing...
Copy constructing...
Copy constructing...
Destructing...
Destructing...
10
20
Destructing...
You can uncomment the move constructor if you want to see that in action as well.
To directly answer your questions:
why this happens? Sincerely, I was expecting just a single instance of the ThreadClass.
This happens because you are passing an object around, so the additional constructors mentioned in the post are getting called multiple times.
In order to avoid unexpected behaviour, is it necessary to overload some of the class operators?
What do you mean by unexpected behavior? This performs exactly how C++ intends. This is well defined behavior for C++.
Upvotes: 2