Как освободить ссылку на аргументы связывания boost :: signal2 :: signal keep? - PullRequest
2 голосов
/ 30 октября 2010

Я обнаружил, что некоторые объекты в моей программе на C ++ не могут быть освобождены из-за того, что Signal2 boost не освобождает эти аргументы в объекте, созданном boost :: bind. Вот код для воспроизведения проблемы:

#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;
}

И вывод выглядит так

Foo is created.
A
B
Foo is deleted.

Я думал, что signal.disconnect_all_slots удалит все соединения. Но на самом деле это не так. Я просто прочитал исходный код сигналов2, кажется, что signal.disconnect только устанавливает флаг «отключить» в тех соединениях, он никогда не удаляет эти объекты. Почему сигнал не удаляет эти отключенные соединения? Разве это не очень странное поведение? В чем причина сохранения этих соединений, а не их удаления? И как заставить его удалить эти соединения?

1 Ответ

0 голосов
/ 30 октября 2010

Обеспечение освобождения соединений представляется уникальным для информации здесь - это для signals, но проблема остается в signals2.

В вашем случае модифицированная версия ниже делает то, что вы хотите, я думаю:

#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;
}

Вывод:

Foo is created.
C 1
D 0
Foo is deleted.
E 0
...