[thread] About the virtual in virtual operator()

View: New views
5 Messages — Rating Filter:   Alert me  

[thread] About the virtual in virtual operator()

by Paul Hilbert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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<ConcretKernel*>
the pointers and I don't want to use maschine-specific ways
like __decltype.

I imagine this is merely the old non-static member function
pointer problem, however I tried dozens of ways to get around
this and the only thing that worked was to add a
ConcreteKernel::run() {
   thread t(*this);
   t.join();
}
to *each* single child class of Kernel which gets rather un-
managable with 50 and more descendants.


I hope that made sense and that I didn't fail that hard,
Richard Vock

_______________________________________________
Boost-users mailing list
Boost-users@...
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Re: [thread] About the virtual in virtual operator()

by Nigel Rantor :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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<ConcretKernel*>
> 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
_______________________________________________
Boost-users mailing list
Boost-users@...
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Re: [thread] About the virtual in virtual operator()

by Paul Hilbert :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> 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!

Richard

_______________________________________________
Boost-users mailing list
Boost-users@...
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Re: [thread] About the virtual in virtual operator()

by Nigel Rantor :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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
_______________________________________________
Boost-users mailing list
Boost-users@...
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Re: [thread] About the virtual in virtual operator()

by Bugzilla from anthony.ajw@gmail.com :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Richard Vock <vock@...> writes:

> 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().

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

_______________________________________________
Boost-users mailing list
Boost-users@...
http://lists.boost.org/mailman/listinfo.cgi/boost-users