[thread] About the virtual in virtual operator()
I don't really know wether this is a Boost.Thread related
question or a general c++ related, but since I couldn't
decide I will disturb you first ;)
Maybe you have the patience to look at this minimalistic
framework (I stripped almost all functionality):
http://pastebin.com/m7dcc833f
This compiles well and running it gives me the expected:
# starting
# This is A
# This is B
# shutting down
The problem is, that I want to run the kernels as threads.
Have (again) a look at the highlighted lines (27-29):
If I replace 27 by 28+29 I (expectedly) get a compile error
since Kernel is abstract. However if I make it non-abstract
by implementing the operator() in it, it is this function
(namely Kernel::operator()) which get's called instead of
TestKernel::operator().
Note that Program will not be able to know about the concrete
child classes of Kernel so it cannot dynamic_cast
Richard Vock wrote:
I don't really know wether this is a Boost.Thread related question or a general c++ related, but since I couldn't decide I will disturb you first ;)
If I replace 27 by 28+29 I (expectedly) get a compile error since Kernel is abstract. However if I make it non-abstract by implementing the operator() in it, it is this function (namely Kernel::operator()) which get's called instead of TestKernel::operator().
Note that Program will not be able to know about the concrete child classes of Kernel so it cannot dynamic_cast
the pointers and I don't want to use maschine-specific ways like __decltype.
There are lots of ways to skin this cat. The smallest change to your code I think would be this though. --- thread t( boost::bind( &Kernel::operator(), m_kernel[i] ) ); t.join(); --- Regards, Nigel
Richard Vock wrote:
The smallest change to your code I think would be this though. --- thread t( boost::bind( &Kernel::operator(), m_kernel[i] ) ); t.join();
I've always had problems understanding boost::bind, but this helps a lot.
And it works too...
Thank you!
I realise this solves your problem but didn't really answer your question though. The reason it doesn't work with an abstract class is because the thread class attempts to copy the functor you're passing in. Since Kernel is abstract you can't do this. If you make Kernel a concrete class you get a different problem. The statement: thread t( *(m_kernel[i]) ) slices the object down to a plain old Kernel, irrespective of what the pointer originally referenced. You can only call virtual functions through pointers or references so you lose dynamic binding once this happens. n
Richard Vock
I don't really know wether this is a Boost.Thread related question or a general c++ related, but since I couldn't decide I will disturb you first ;)
Maybe you have the patience to look at this minimalistic framework (I stripped almost all functionality):
This compiles well and running it gives me the expected:
# starting # This is A # This is B # shutting down
The problem is, that I want to run the kernels as threads. Have (again) a look at the highlighted lines (27-29):
If I replace 27 by 28+29 I (expectedly) get a compile error since Kernel is abstract. However if I make it non-abstract by implementing the operator() in it, it is this function (namely Kernel::operator()) which get's called instead of TestKernel::operator().
Yes. This is because boost::thread copies the objects into the new thread. You can't copy an object through a reference to abstract base since you cannot create an instance of the base class. If you make the base non-abstract then it slices, and calls the base operator(). You can use boost::ref to fix this: boost::thread t(boost::ref(*m_kernel[i])); Of course you have to ensure that the m_kernel objects outlive the threads if you do this. Anthony -- Author of C++ Concurrency in Action | http://www.manning.com/williams just::thread C++0x thread library | http://www.stdthread.co.uk Just Software Solutions Ltd | http://www.justsoftwaresolutions.co.uk 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
participants (3)
-
Anthony Williams
-
Nigel Rantor
-
Richard Vock