Very dangerous examples are given. Take a look:
#include <iostream> #include <memory> #include <boost/signals2.hpp> struct object_with_slot { object_with_slot() { std::cout << "ctor\n"; } object_with_slot(const object_with_slot &) { std::cout << "cctor\n"; } ~object_with_slot() { std::cout << "dtor\n"; } void operator()() { std::cout << "Slot called!" << std::endl; member = 50500; } int member; }; // int main() { typedef boost::signals2::signal<void ()> sig_type; sig_type sig; std::shared_ptr<object_with_slot> ptr(new object_with_slot); sig.connect(sig_type::slot_type(*ptr).track_foreign(ptr)); // ptr is tracked sig(); return 0; }
What do you think this code does (g ++ 4.8.1, libboost 1.54)?
ctor cctor cctor cctor cctor cctor cctor cctor cctor dtor dtor dtor dtor dtor cctor dtor cctor dtor dtor dtor cctor dtor Slot called! dtor dtor
I do not think this behavior was expected. Since we are passing a copy (by value) *ptr (an instance of object_with_slot ) to the connect method. This can be solved, for example, with reference wrappers:
sig.connect(sig_type::slot_type(boost::ref(*ptr)).track_foreign(ptr));
Be careful with patterns and types.
source share