2010-10-30 2 views
2

J'ai trouvé que certains objets de mon programme C++ ne peuvent pas être libérés en raison du Signal2 de boost ne relâchera pas ces arguments dans l'objet créé par boost :: bind. Voici le code de reproduire le problème:Comment libérer la référence des arguments bind boost :: signals2 :: signal keep?

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

Et la sortie ressemble à ceci

Foo is created. 
A 
B 
Foo is deleted. 

Je pensais que les signal.disconnect_all_slots supprimeraient toutes les connexions. Mais en réalité, ce n'est pas le cas. Je viens de lire le code source de signaux2, il semble que le signal.disconnect seulement mettre un drapeau "déconnecter" dans ces connexion, il ne supprime jamais ces objets. Pourquoi le signal ne supprimera pas ces connexions déconnectées? N'est-ce pas un comportement très étrange? Quelle est la raison de garder ces connexions plutôt que de les supprimer? Et comment le forcer à supprimer ces connexions?

Répondre

0

Garantir la libération des connexions semble être idiosyncratique selon l'information here - ceci est pour signals, mais le problème reste dans signals2.

Dans votre cas, la version modifiée ci-dessous ce que vous ne voulez, je pense:

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

Sortie:

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

Je suis désolé, l'exemple que je fournis ici est une version simplifiée. Je l'utilise dans un serveur boost :: asion. sconped_connect ne peut pas fonctionner. –

Questions connexes