7
votes

Alternatives à la transmission d'un pointeur à vous-même aux objets que vous possédez

Je fais cela beaucoup:

class Child{
  Control*parent;
public:
  Child(Control*theParent):parent(theParent){}
 };

class Control{
 Child child;
 void makeChild(){ child=Child(this); }
 //Control() : child(this) { }  //another example
 }


3 commentaires

Nice question, je le fais beaucoup et je me suis demandé (et je me demandais toujours) s'il y a une alternative pour cela.


Cela devrait être plus comme Control (): Enfant (this) {} , ne devrait-il pas?


@Kerreksb oui j'ai tapé le pseudocode sans le compiler; Je l'ai corrigé


4 Réponses :


2
votes

On dirait que vous recherchez le modèle d'observateur.

Dans le modèle d'observateur, un objet conserve une liste de personnes à charge (AKA observateurs) et les notifie les modifications requises. Dans votre cas, la classe contrôle est l'observateur et la classe enfant est le notifiant.

La bibliothèque de boost a un mécanisme de signal / emplacement qui peut être utilisé pour implémenter ceci: http://www.boost.org/ doc / libs / 1_49_0 / doc / html / signaux / tutoriel.html # ID3137144

Il y a un exemple d'utilisation de cela sur SO: Exemple complet à l'aide de Boost :: Signaux pour C ++ Evénement


6 commentaires

Idée intéressante; J'aurais pensé qu'il y aurait un moyen de faire quelque chose dans la langue fondamentale.


Pas encore, mais j'ai entendu dire que cela sera discuté pour C ++ 14.


Consultez l'autre réponse pour un exemple de motif d'observateur sans renforcement en C ++


Si ce que vous allez utiliser cela n'est pas trop compliqué et ne changera pas trop, je recommanderais de jeter un coup d'œil à la réponse de Mikkel pour une implémentation purement «principale».


BTW Il y a des différences ... dans la version de boost, je pense que le mécanisme de signal / emplacement est obtenu entièrement à l'aide de modèles, c'est-à-dire aucun héritage. Donc, il n'y a pas de frais généraux d'exécution. Cela peut être important pour vous.


@Sebbyjohanns: l'autre réponse a le même problème que la réponse 3ème , car les réponses continuent à apparaître et sont commandées en direct en fonction de leur score, une telle référence devient bientôt ambigu . Suppression de la barrage, il est préférable de faire référence à des réponses par nom de leur auteur (pour des références amicales) ou directement en reliant.



3
votes

Vous pouvez les séparer par une interface: xxx

(Il s'agit d'une version simple du modèle d'observateur, BTW).


8 commentaires

Votre notifier dans la classe de base doit être virtuel mais sinon cela semble bon


Merci. J'ai écrit trop de Java ces derniers temps.


Je préférerais utiliser un adaptateur avec une délégation sur l'héritage et fournir une interface de contrôle étroite plutôt qu'un observateur générique, mais sinon c'est ainsi que je vais aller (c:


@Billyonéal: pas nécessairement et -WDelete-non-virtuel-dtteur mettra en garde sur tout problème de toute façon.


@Peterwood je profiterais de l'élaboration de la suggestion que vous faites, peut-être comme une autre réponse.


@Matthiez oui nécessairement. Tout le monde n'utilise pas GCC. Soit autoriser la suppression par pointeur en faisant le destructeur virtuel, ou interdit explicitement en le faisant protégé. Il n'y a aucune raison de faire fonctionner une classe de base.


@Billyonéal: En fait, je l'ai mis en place à Clang d'abord et les gens de la GCC la pillaient;) Mais je suppose que MSVC pourrait être en traînant derrière là: x


@Matthieu: Oui, EDG et ICC sont à la traîne par derrière cette métrique.



0
votes

Jeter une autre idée dans la bague, il semblerait qu'un classe d'amis peut aller longtemps manière avec cela aussi.

Méthodes qu'un enfant ne doit pas avoir accès à des privé ou protégé . De cette façon, l'enfant ne peut pas faire de dégâts que vous ne voulez pas que ce soit.

Ensuite, si vous avez besoin d'une autre classe pour gérer votre contrôleur parent, votre classe mère fait que l'autre catégorie A ami afin qu'il puisse accéder à toutes ces méthodes privées que vous retenez de l'enfant.


0 commentaires

0
votes

Lorsque j'ai lu des sujets généraux sur les modèles de conception du programme, etc., il semble que cette méthode d'organisation d'objets n'est pas particulièrement recommandée.

C'est tellement faux, à cause de Inversion du contrôle . Vous auriez pu la créer comme variable de membre enfant . Martin Fowler a un très bel article Expliquer un type d'inversion de contrôle (injection de dépendance).

Voici un exemple expliquant brièvement comment implémenter une injection de dépendance (dépendance injectée à travers le constructeur): xxx


si vous pensez des modèles de conception, vous " Notez que certains d'entre eux utilisent une sorte d'inversion de contrôle. Voici certains bien connus (de ce lien ):


1 commentaires

Essentiellement ce que j'ai démontré, c'est une injection de dépendance, alors pouvez-vous expliquer ce que vous voulez dire quand vous dites que je le fais "mal"? Votre exemple est également l'injection, via constructeur. Cela est inclus dans mon exemple aussi comme exemple.