$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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