2009-02-14 5 views
4

Je fais mon boost::signal du public parce que je suis paresseux.boost :: Public objet signal

class Button { 
public: 
    signal<void()> clicked; 
}; 

int main() { 
    Button btn; 
    btn.clicked.connect(handleClick); 
} 

... plutôt que l'encapsulation avec un Button::OnClicked(boost::function<void()>).

Est-ce que ça va revenir et me mordre?

Répondre

3

Cela dépend.

Il m'a mordu avant quand je voulais ajouter une logique particulière à chaque fois un objet relié aux signaux d'un autre objet. C'est le cas le plus probable pour vous mordre. En outre, il peut être difficile de garder une trace exactement quand d'autres objets se connectent à un objet donné. Je dirais cacher les connexions derrière une fonction pour être du bon côté.

Je l'habitude d'utiliser une macro pour faire la définition de la fonction de vanille.

#define SIGNAL(slot,name) connection name(function<slot> func) { return _##name##.connect(func);} 

Et puis dans une définition de classe:

SIGNAL(void(),clicked) 

Cela suppose que vous suivez la convention de nommer le signal '_clicked', mais vous pouvez remplacer une convention. Il garde généralement l'interface plus propre pour toutes vos classes. Lorsque vous voulez ajouter une logique de connexion spéciale, vous pouvez, sans changer tous les autres objets qui utilisent le signal.

EDIT

Un exemple est lorsque l'objet de signal a été effectivement déplacé à une mise en œuvre des délégués dans une autre classe, mais il a encore un sens pour les objets à se connecter via la classe d'origine. Cela a brisé tous les endroits qui essayaient de s'y connecter. S'ils utilisaient des accesseurs de fonction pour se connecter, cela aurait été aussi simple que de changer la fonction pour rechercher le signal dans le délégué. Mais comme c'était il a cassé tous les utilisateurs de la classe originale. Ou, quand je voulais enregistrer à chaque fois quelque chose connecté à un signal spécifique. C'était juste à des fins de débogage, mais cela peut être très utile si vous suspectez que quelque chose de bancal se passe comme des cycles dans vos connexions de signal.

+0

merci; Pouvez-vous me parler d'un cas précis où vous en aviez besoin? –

0

Eh bien, cette question n'a vraiment rien à voir avec boost::signal ou function - c'est une question d'encapsulation.

Les clients de la classe Button ont-ils besoin d'un accès complet à clicked? Si tout ce qu'ils devraient être en mesure de faire est de s'y abonner, n'autorisez que cela avec la méthode OnClicked. Exposer plus de que est susceptibles de vous mordre à mon humble avis.

Comme toujours vous équilibrer les coûts vs avantages. Dans ce cas, le coût est très faible. Si vous étiez dans mon équipe, je vous recommande fortement d'ajouter la méthode OnClicked.

0

Je les ai mis en public aussi bien et utiliser chamelle majuscules pour le nom de l'objet. Cette approche ne s'est jamais retournée contre moi.

2

Je suis tombé sur une bonne raison pas pour ce faire.

Nous cherchons à utiliser une bibliothèque tierce qui expose les signaux boost :: sur une interface externe. Cette bibliothèque dépend d'une version de boost avec un ensemble de définitions de compilateur qui sont incompatibles avec les définitions de compilateur Visual Studio standard que nous utilisons dans notre projet. Chaque fois que nous essayons d'appeler le signal.connect de la bibliothèque tierce, les choses meurent.

La solution pour nous est soit:

  1. recompiler tous notre source et les bibliothèques dépendant de la version boost fournie par eux.
  2. Enveloppez les signaux d'amplification et masquer la mise en œuvre

Quelque chose à considérer, au moins!

Questions connexes