10
votes

Appeler automatiquement la fonction lorsque des modifications variables

Y a-t-il une manière en C ++ pour appeler automatiquement une fonction lors de la modification de la valeur d'une variable?


0 commentaires

7 Réponses :


9
votes

en un mot; non.

Mais ce que vous devriez faire, c'est envelopper la variable dans une classe (je ne vais pas suggérer une surcharge sur l'opérateur) et la modifier via une fonction définie (...). Ensuite, vous appelez simplement la fonction de la fonction définie.


4 commentaires

En un mot: oui. Avec une quantité modérée d'effort, un auditeur peut surveiller la variable des modifications apportées à un programme multi-threadé et des fonctions d'appel en conséquence. Même dans un système non multithreadé, cela pourrait fonctionner, bien que ce soit un peu de hack. Je ne dis pas que je le recommande, car l'option Setter est (probablement) mieux, mais de dire que cela ne peut pas être fait est simplement incorrect.


@Glow qui ne sonne pas comme une fonction incluse avec C ++, ce qui semble être ce que l'OP a demandé


@Michael ce n'est pas comment je l'interprète du tout. On dirait qu'il veut que la capacité d'appeler une fonction quand quelque chose se change et de le faire en C ++. Il ne semble pas préciser intégré ou non, au moins à ces yeux.


@Glow, je suppose qu'il serait probablement heureux d'une solution, mais "Y a-t-il une fonction en C ++" me fait penser qu'il veut juste appeler détect_changes (& var, my_function_pointer);



2
votes

Non, vous devez encapsuler la variable dans quelques méthodes Get / Set.


0 commentaires

3
votes

Vous pouvez rendre la variable privée à une classe, puis utiliser des fonctions membres pour le changement de la première place.

Vous pouvez mettre votre code supplémentaire dans la fonction membre elle-même, ou vous pouvez disposer de ce code séparé et que la fonction membre l'appelait sur le changement.


0 commentaires

14
votes

existe une fonction dans C ++ que lorsqu'une variable a changé, il appelle automatiquement une fonction?

Non, pas que je puisse penser à. Cependant, vous pouvez envelopper l'accès à la variable dans une enveloppe appropriée qui vous permet de vous accrocher à l'affectation.
Quelque chose comme ceci: xxx

comme Noah noté dans un commentaire, xxx

(ou si votre compilateur l'a fait, std :: tr1 :: fonction ou std :: fonction ) améliorerait considérablement cela, car il permet d'appeler toutes sortes de fonctions "compatibles". (Par exemple, il permet toutes sortes de magie à l'aide de boost / std :: / tr1 :: lid <> pour appeler les fonctions des membres et ce que rien.)

Notez également que, comme ADF88 a déclaré dans ses commentaires, cela fait simplement ce qui a été demandé (surveiller l'accès en écriture à une variable) et n'est en aucun cas une implémentation de biens à part entière. En fait, malgré l'attitude de C ++ de mettre en œuvre autant que possible dans les bibliothèques et aussi peu que possible dans la langue, et malgré les tentatives de nombreuses personnes (certaines d'entre elles plutôt intelligentes), personne n'a trouvé de moyen de mettre en œuvre des propriétés en C ++. comme une bibliothèque , sans supporter de la langue.


16 commentaires

Ne pensez-vous pas que cela complique trop? Qu'en est-il des autres opérateurs? Qu'en est-il de prendre une adresse? Vous freinez la sémantique ici. Si le compilateur ne prend pas en charge les propriétés, ce n'est pas une bonne solution pour les simuler. -1


@ ADF88: Que voulez-vous dire, "complique trop"? Si vous voulez faire ce que le questionneur posait, alors cela est aussi simple que possible. En ce qui concerne votre dernier point, le compilateur ne prend pas directement en charge des tableaux, des objets de fonction, des pointeurs intelligents, des métaprogramming de modèle ou de nombreux autres concepts qui sont devenus des idiomes courantes (ou même standard) C ++ en écrivant le code pour «simuler».


Utilisation de Boost :: Fonction et / ou Boost :: Les signaux (2) en feraient une meilleure solution imho.


Écraser le = l'opérateur..qui un tour froid. IMHO, bien meilleur que les hacks Getter / Setter recommandés par la pensée polluée Java. Dans certains projets Java, je me suis battu de la malbouffe de getter / setter et j'ai toujours souhaité que nous puissions remplacer l'opérateur = comme ci-dessus. Un bon exemple est une variable que vous avez définie une fois au moment de l'exécution et lancez une exception si elle est retenue.


@ ADF88: Prendre l'adresse n'a pas été demandé. Ni aucune autre opération, FTM. Comme Mike a dit: la plupart de C ++ est mise en œuvre comme des bibliothèques. Si nous devions nous tenir à ce que le compilateur fournit, nous serions coincés dans les années 80. (Et tous ceux qui se souvient de leur musique ne veulent pas y retourner!)


@ User1: struct test {test (int i): i_ (i) {} const int i_; }; attraperait des tentatives de modification de i _ au moment de la compilation.


@NOAH: J'ai effectivement pensé à Boost :: Fonction <>, mais je ne voulais pas gâcher cette solution facile avec elle. Je voulais dire cela, mais je l'ai oublié. Alors merci d'avoir apporté cette question. Je vais ajouter un indice à la réponse.


Il est impossible de simuler des propriétés en C ++ (j'ai mentionné de nombreux problèmes). Toute mise en œuvre ne serait pas bonne, ne serait pas hermétique. Prendre une adresse est très important ici - le compilateur ne vous avertira pas si vous le faites. Simple Setter / Getter est le meilleur ici car il vous protège de faire des erreurs.


@ ADF88: Si vous lisez attentivement, vous verrez que c'était vous qui a soulevé le terme «propriétés». Homme de paille?


C'est peu importe comment voudriez-vous nommer cela. Ce n'est pas hermétique et peut conduire à des erreurs.


@ ADF88: Non, ce n'est pas hermétique, il fait exactement ce qui a été demandé à l'autre et rien d'autre. Mais alors, personne n'avait affirmé que ce serait hermétique et ignifuge. C'est juste une paillette que vous continuez à frapper.


@ User1: Si vous êtes uniquement autorisé à définir / l'attribuer une fois, pourquoi ne pas simplement le mettre dans le constructeur?


Derniers mots de moi: "Cela fait exactement ce qui lui a été demandé et rien d'autre" - votre droit, mais votre réponse n'est pas bonne. Pourquoi? Si quelqu'un ne sait pas comment faire quelque chose, il imagine parfois des mauvaises solutions, un mauvais concept. Vous avez écrit une solution réalisant un mauvais concept. Vous jouez dans la tête de Noob. La réponse évidente est de changer le concept - ne "détecter" pas lorsque la variable est modifiée; Écrivez plutôt une fonction et appelez cette fonction dans des endroits où vous définissez la valeur de la variable.


@ ADF88: Je peux voir que cela pourrait aider à ajouter un avertissement à ma réponse et je suis allé et l'ai fait. Je crois encore, cependant, que pour la tâche donne, c'est une solution bonne et valide.


Puis-je faire émuler ce comportement en C? Les pointeurs opaques peut-être? ou y a-t-il d'autres méthodes?


@ Trailing99: J'en doute. C n'est pas adapté à de telles abstractions.



1
votes

Selon la complexité de votre programme, vous pouvez utiliser des auditeurs qui surveillent certains objets pour des modifications de l'état et que d'autres parties de votre programme sont souscrives à des événements à partir de cet auditeur.

Cependant, la meilleure option serait de placer cette fonctionnalité dans la méthode Setter pour cette variable. Il pourrait s'agir de la fonctionnalité d'auditeur ou d'un appel de fonction directe.


0 commentaires

0
votes

Vous pouvez encapsuler cette variable et avoir des auditeurs qui sont notifiés lorsque la valeur change. J'irais avec boost :: signaux ou boost :: signaux2 pour cela:

http://www.boost.org/doc /Libs/1_43_0/doc/html/signals2.html

Et voici quelques informations sur le motif observateur: http://en.wikipedia.org/wiki/observer_pattern


0 commentaires

1
votes

Si la variable a un type de classe, vous pouvez surcharger son opérateur = () fonction. Vous ne pouvez pas faire cela si la variable est un type primitif.


0 commentaires