I have something along the lines:
class Parent
{
private:
std::thread t1;
protected:
void ThreadFunction()
{
while(true)
{
SpecializedFunction();
}
}
void CreateThread()
{
t1 = std::thread(&Parent::ThreadFunction, *this);
}
virtual void SpecializedFunction() = 0;
public:
void Run()
{
CreateThread();
}
}
class Child1 : public Parent
{
protected:
void SpecializedFunction()
{
//code
}
}
class Child2 : public Parent
{
protected:
void SpecializedFunction()
{
//code
}
}
But I have compile errors(It compiles if I comment the thread creation line). It says that it cannot specialize the decay method. I think the problem is either that Parent is abstract, either that the thread function is protected, but I'm not sure. Could you suggest a workaround/a solution?
Thanks!
t1 = std::thread(&Parent::ThreadFunction, *this);
This will create a copy of *this
and run the member function on the copy. In your case that fails, because you cannot create a copy of an abstract class, but making a copy is probably not what you wanted anyway.
To run the thread on the existing object pass a pointer:
t1 = std::thread(&Parent::ThreadFunction, this);
or (since the resolution of LWG 2219) a reference:
t1 = std::thread(&Parent::ThreadFunction, std::ref(*this));
As T.C. says in a comment above, you must ensure the object's lifetime does not end while the new thread is still running. You can do this by joining it in the destructor:
~Parent() { if (t1.joinable()) t1.join(); }
(If you don't join a std::thread
before it is destroyed your program will terminate immediately!)
This is still not quite safe, because it only ensures the base class is not destroyed while the thread is still running, but the thread could be accessing the derived class, so you might need to ensure the thread is joined in the derived destructor.