Consider this:
#include <boost/signals2.hpp>
#include <iostream>
struct object_with_slot
{
void operator()()
{
std::cout << "Slot called!" << std::endl;
member = 50500;
}
int member;
};
int main()
{
boost::signals2::signal<void ()> sig;
object_with_slot * ptr = new object_with_slot;
sig.connect(*ptr);
delete ptr;
sig();
}
Output is "Slot called!" and no crash or anything. That's why I have a few questions:
1) Why there is no crash?
2) Why there is no crash even if the slot function assigns something to object which doesn't exist?
3) How can I make the signal automatically track the lifetime of its slots? I mean when the slot is destroyed, it gets disconnected.
The question number 3 is the most important, as I need to implement observer pattern and very often lifetime of observers (slots) won't be static (for the whole time when app is running).
Very dangerous examples are given. Take a look:
How do you think, what does this code out (g++ 4.8.1, libboost 1.54)?
I don't think, that this behaviour was expected. Because we pass copy (by value) of
*ptr
(instance ofobject_with_slot
) to theconnect
method. It might be solved, for example, by reference wrappers:Be careful with templates and types.
1) You're lucky. If not, you'll get a segmentation fault.
2) The memory was not overwritten in any way.
3) You could use slot::track to automatically disconnect when the tracked object gets deleted. Boost.Signals2 could track objects that are managed by boost::shared_ptr.
UPDATE:
Added code to track objects for std::shared_ptr and std::weak_ptr:
1 and 2) In fact it is an undefined behaviour. You employed the dereference operator, now connect has the value of the object_with_slot, its address is free to be assigned by memory manager to any other process. By coincidence it is still a "valid address". And ptr is free to be assigned to any other value without cause memory leak.
Try something like this and you will see that explodes everytime
3) You can put another signal on destructor of object_with_slot, then it can notify when it is called.