I found some objects in my C++ program can't be released due to the Signal2 of boost won't release those arguments in object created by boost::bind. Here is the code to reproduce the problem:
#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/signals2.hpp>
#include <boost/shared_ptr.hpp>
using namespace std;
using namespace boost;
class Foo {
public:
Foo() {
cout << "Foo is created." << endl;
}
~Foo() {
cout << "Foo is deleted." << endl;
}
};
typedef shared_ptr<Foo> FooPtr;
typedef signals2::signal<void ()> Signal;
void bar1(FooPtr pFoo) {
}
void bar2(Signal &s) {
FooPtr pFoo(new Foo());
s.connect(bind(bar1, pFoo));
}
int main() {
Signal signal;
bar2(signal);
cout << "A" << endl;
signal.disconnect_all_slots();
cout << "B" << endl;
return 0;
}
And the output looks like this
Foo is created.
A
B
Foo is deleted.
I thought the signal.disconnect_all_slots would delete all connections. But actually, it didn开发者_运维问答't. I just read the source code of signals2, it seems that the signal.disconnect only set a flag "disconnect" in those connection, it never delete those object. Why the signal won't delete those disconnected connections? Isn't it a very strange behavior? What is the reason of keep those connections rather than delete them? And how to force it to remove those connections?
Ensuring release of connections appears to be idiosyncratic per the info here - this is for signals
, but the issue remains in signals2
.
In your case, the modified version below does what you want, I think:
#include <boost/bind.hpp>
#include <boost/signals2.hpp>
#include <boost/scoped_ptr.hpp>
using namespace std;
using namespace boost;
class Foo {
public:
Foo() {
cout << "Foo is created." << endl;
}
void bar()
{
}
~Foo() {
cout << "Foo is deleted." << endl;
}
};
typedef signals2::signal<void ()> Signal;
int main() {
Signal signal;
{
scoped_ptr<Foo> foo(new Foo);
signals2::scoped_connection c =
signal.connect(boost::bind(&Foo::bar, foo.get()));
cout << "C " << signal.num_slots() << endl;
signal.disconnect_all_slots();
cout << "D " << signal.num_slots() << endl;
}
cout << "E " << signal.num_slots() << endl;
return 0;
}
Output:
Foo is created.
C 1
D 0
Foo is deleted.
E 0
精彩评论