I have the requirement of invoking a pure virtual method implementation when spawning a thread from within a base class method as shown below.
#include <iostream>
class Foo {
private:
std::thread tr;
public:
virtual void baz() = 0;
void foo() {
this->tr = std::thread([=] { this->baz(); });
}
};
class Bar : public Foo {
public:
void baz() {
std::cout << "In baz" << "\n";
}
};
Main class...
#include <thread>
#include "test.hpp"
int main(int argc, char* argv[]) {
Bar b;
b.foo();
}
But it fails with the message
terminate called without an active exception
pure virtual method called
The message "pure virtual method called" appears only in some of the failure messages. What am I doing wrong? Is it something related to Bar or the thread getting improperly destructed?
As Igor pointed out in his comment, you have a data race. The thread is actually executed after Bar
gets destroyed (the actual order of execution is not defined, of course, so you may get lucky sometimes). To prevent this, you need to tr.join();
before Bar
gets destroyed.
class Foo {
std::thread tr;
protected:
void join() { tr.join(); }
public:
virtual ~Foo() = default; // ~Foo should be virtual or protected, if Foo contains virtual methods
virtual void baz() = 0;
void foo() {
this->tr = std::thread([=] { this->baz(); });
}
};
class Bar : public Foo {
public:
~Bar() { join(); }
void baz() { std::cout << "In baz" << "\n"; }
};
If you want to investigate this more, add some cout
s in various methods (especially the destructors), and add a std::this_thread::sleep_for (std::chrono::seconds(1))
at various places.