Boost logo

Boost Users :

From: Sebastian Redl (sebastian.redl_at_[hidden])
Date: 2006-02-05 13:13:19


Evan Carew wrote:

>Hmm, have you even used signals before? The manual for it was the
>basis of my example program. I don't think you would have said that if
>you had used the library before.
>
>
Which part of the manual?

I have used Signals before, but I admit that I've never been in a
situation where the destructor of my signal would have been relevant.
Nevertheless, I'm very curious as to what prompted you to assume that I
haven't used the library.
I'm browsing the docs right now, and there is hardly any mention of what
happens with the slot object, beyond that it's passed to connect() by
const reference. This does not, however, mean that it is stored
internally as a reference. In fact, since the const reference allows you
to pass a temporary, such behaviour would be catastrophic.
The first block of the design overview, "Type Erasure", hints that
Signals stores the slot objects as Boost.Function objects. So let's go
to that library's documentation and see what they have to say on the matter.
Boost.Function says, in the documentation of functionN::functionN(F):

> *Postconditions*: |*this| targets a copy of |f| if |f| is nonempty, or
> |this->empty
> <http://www.cppdoc.local/boost/doc/html/functionN.html#id1001382-bb>()|
> if |f| is empty.

In other words, the object is copied into the Function, not referenced.
The tutorial also states that if you wish that no copying is done, you
should use boost::ref or boost::cref to wrap the object.

Internally, Signals will then proceed to store the function object
somewhere. It is not unreasonable to assume that four temporary copies
of the Function object are created. And as functionN::functionN(const
functionN&) states:

> *Postconditions*: Contains a copy of the |f|'s target, if it has one,
> or is empty if |f.empty
> <http://www.cppdoc.local/boost/doc/html/functionN.html#id1001382-bb>()|

Again a copy of your own object will be created. Thus, when temporary
Function objects get created, temporaries of your type are also created.
And destructed again, calling the destructor of your object. (On a side
note, I would recommend against calling it the "delete function". Delete
has a very specific meaning in C++, and while it has something to do
with destructors, it's still something entirely different.)

So, on to the solution of your problem that you asked for in the other mail.
Solution 1) Don't depend on the destructor of your slot object. Slot
objects should be largely trivial. I would recommend this solution.
Solution 2) If you really HAVE to depend on the destructor (say, because
for some reason you have a big, stateful slot object), you can follow
Function's tutorial and wrap the object in a boost::ref or boost::cref.

Sebastian Redl


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net