Based on C++ polymorphism with variadic function parameter I tried to write similar (non-templated, with constructors) program
code:
#include <thread>
#include <iostream>
#include <vector>
class Base
{
public:
Base (int count) { run(count); } // this-> does not help
virtual void run (int count) { // non-virtual does not help eighter
for (int i=0; i<count; ++i)
threads.emplace_back(std::ref(*this));
}
virtual ~Base () {
for (auto& t : threads)
t.join();
}
virtual void operator() () = 0;
protected:
std::vector< std::thread > threads;
};
class Derived : public Base
{
public:
using Base::Base;
virtual void operator() () { std::cout << "d"; }
};
int main()
{
Derived d(4);
std::cout << std::endl;
return 0;
}
expected result:
dddd
real result (Ubuntu 14.04, gcc v4.8.2):
pure virtual method called
pure virtual method called
terminate called without an active exception
terminate called without an active exception
dAborted (core dumped)
Please notice, that Derived::operator()
was at least once really called (d
on the last line, almost always).
Even though the code is dead simple and almost same as original (see link above) it does not work. I spent literally hours solving this problem.
Target is to construct Derived
with a number of threads. This amount of threads will be executed (in constructor) and joined in destructor. operator()
should be used as thread-body function (as in the original code). Moreover, it should be virtual in order to provide polymophism.
As far as I'm concerned run
passes *this
(for some reason) typed as Base
, not Derived
, so threads execute Base::operator()
which is pure virtual
Additional question: is there any way labeling operator()
protected?
Can anybody help me out? Thanks.
EDIT:
According to Billy ONeal's answer I rewrote the code, so Derived
constructor calls the run
, but without any success
#include <thread>
#include <iostream>
#include <vector>
class Base
{
public:
virtual void run (int count) { // non-virtual does not help eighter
for (int i=0; i<count; ++i)
threads.emplace_back(std::ref(*this));
}
virtual ~Base () {
for (auto& t : threads)
t.join();
}
virtual void operator() () = 0;
protected:
std::vector< std::thread > threads;
};
class Derived : public Base
{
public:
Derived (int count) { run(count); }
virtual void operator() () { std::cout << "d"; }
};
int main()
{
Derived d(4);
std::cout << std::endl;
return 0;
}
Results vary over the time - here are all I have ever got
1) d
2) dd
3) ddd
4) dddd
5) d
pure virtual method called
terminate called without an active exception
ddAborted (core dumped)
Especially 5)
I can't explain.
I've added {...}
around Derived d(4);
as an anonymous block to force destructor execution before the endl of line end program termination, but since that I've got only
pure virtual method called
terminate called without an active exception
ddAborted (core dumped)
Your code has a race condition (and therefore undefined behavior). When you start the thread in Base
's constructor, the thread will immediately try to call operator()
on that object. But Derived
's constructor hasn't run yet, so operator()
is still the one from Base
, which is pure virtual. Another valid execution would be that Base
's constructor and Derived
's constructor finish before the threads actually get going, which would give the behavior you expect, but that result is unlikely.
Your comment about this->run
not helping makes sense because the output complains about a pure virtual member function being called, and run
is not a pure virtual member, only operator()
is.