8
votes

Dérivation juste à temps

Il y a un idiome C ++ moins commun que j'ai utilisé à bon effet plusieurs fois dans le passé. Je n'arrive tout simplement pas à me souvenir s'il a un nom généralement utilisé pour le décrire.

C'est un peu lié à Mélangements , CRTP et Effacement de type , mais n'est pas spécifiquement aucune de ces choses.

Le problème est trouvé Lorsque vous souhaitez ajouter une implémentation à une classe, mais que vous ne voulez pas la mettre dans la classe ou de toute classe qu'il dérive. Une des raisons pourraient être que la classe pouvait faire partie d'une hiérarchie d'héritage où la mise en œuvre ne devrait se produire qu'une fois.

Mise de côté, pour le moment, des problèmes tels que si une hiérarchie doit avoir des classes non-feuilles concrètes, ou si l'héritage virtuel peut être une option dans certains cas, je sais qu'une solution pour fournir la mise en œuvre Dans une classe de modèle qui dérive de son paramètre de modèle. Cela vous permet ensuite d'utiliser le modèle lorsque vous créez une instance, mais n'utilisez alors que l'objet par pointeur ou que vous vous référez à l'une de ses bases (c'est là que l'effacement du type, en lâche, est disponible).

Un exemple peut être que vous avez un compte de référence intrusif. Toutes vos classes dérivent d'une interface de comptage Ref, mais vous ne voulez que le dépôt de référence lui-même et la mise en œuvre de vos méthodes de comptage REF, pour apparaître une fois, vous les mettez donc dans le modèle dérivé - appelons-le implsementrc . Maintenant, vous pouvez créer une instance comme si: xxx

Je suis brillant sur des choses comme des constructeurs de transfert formés de multiples surcharges modèles, etc.

alors, espérons-le. J'ai précisé ce que l'idiome est. Retour à ma question - y a-t-il accepté, ou au moins généralement généralement utilisé, pour cet idiome?


14 commentaires

Semble en quelque sorte liée au motif de visiteur ou au polymorphisme externe ... mais pas tout à fait.


Je ne vois pas vraiment comment c'est lié à l'un de ces modèles - soins à élaborer?


En fait, cela n'utilise même pas CRTP. J'ai mentionné CRTP ici parce que cela ressemble à l'inverse de CRTP.


@Andreas - avec CRTP C'est la classe de base qui est un modèle, où l'argument de modèle est le type de la classe dérivée. Avec l'idiome, j'ai décrit, sa classe dérivée qui est un modèle dans lequel l'argument de modèle est le type de la classe de base.


N'est-ce pas ImplementsRC CRTP? Ne ImplemplementsRC hérite concreteclass ?


@Phil Aha, (j'ai écrit mon commentaire avant de voir votre réponse)


@Phil tu veux dire: base de structure : dérivé


@Andreas - oui, c'est à peu près


Peut-être que cela n'a pas de nom. Il est temps de coder une.


N'est-ce pas une version spécifique du modèle du modèle de pont?


@GF Je n'avais pas vraiment pensé à cela en termes de pont. Je peux certainement voir des éléments de pont là-bas, mais je ne suis pas sûr que je disais vraiment que c'est ce que c'est. De toute façon, c'est la technique de Mise en œuvre Ceci est intéressant (au moins pour moi). Pour mettre un autre moyen - que ferriez-vous appeler la classe qui fait le travail (je l'ai appelé implémentation dans l'exemple spécifique, mais si vous vouliez généraliser ...)? Je ne pense pas que tu appellerais ça pont.


Il y a une différence importante dans vous, que vous ajoutez à la fonctionnalité de fonctionnalité de concreteclass ou fournissez des fonctionnalités entièrement non liées, je ne pense pas que vous puissiez généraliser cela simplement parce que la syntaxe ressemble à la même chose.


@GF Ce que je fais en fait dans ce cas, vous fournissez la mise en œuvre de la classe dérivée pour certaines méthodes d'interface que la classe de base dérive. Pour être générique, la mise en œuvre doit être orthogonale à la classe de base par définition (d'où l'exemple de compte REF).


Ok, je semble avoir manqué l'orthogonalité.


9 Réponses :


0
votes

ressemble à PIMPL Idiom ? Peut-être utilisé de manière inhabituelle.


1 commentaires

Non, ce n'est pas vraiment un bouton. C'est juste pour déplacer les courages de la mise en œuvre pour minimiser les dépendances - cela le diffèrent à une classe qui n'est utilisée que au point d'instanciation.



1
votes

Je ne suis pas sûr que cela a un nom, comme le suggérait GF, il ressemble un peu à la tendance du pont. C'est presque comme votre accrochage de fonctionnalité à la classe de base.

Je suggère un nouveau nom pour cela, le PIMP idiom. Comme vous éteignez votre classe de base;)


1 commentaires

+1 Pour suggérer le pimp idiome :-) Si nous devions bien miser le nom ici, j'aime celui-ci. Malheureusement, je devrais aussi devoir le rejeter car il y a trop de portée à la confusion avec le pimpl idiome ;-) pont WRT, voir ma réponse aux commentaires de GF.



0
votes

Je ne suis pas sûr, mais est-ce "Membre vide Optimisation C ++"?

et un tel type de comportement est mis en œuvre à l'aide de modèles de classes et héritage privé . .

Il est expliqué dans l'article de magazine nommé "Objets de comptage en C ++" par Scott Meyer.


1 commentaires

L'article de Scott est à propos de CRTP. Il s'agit de "Inverse" de CRTP (c.-à-d. Modèle STRIT dérivé: T {}; vs struct dérivé: base publique {}; )



1
votes

Recherchez-vous le Modèle de décorateur ?

Fondamentalement, le décorateur est un objet qui renferme un autre objet et étend la fonctionnalité de certaines méthodes. Les appels de méthode sont ensuite transmis à la méthode ci-jointe.


2 commentaires

Il y a certainement une résonance avec décorateur, tout comme il y en a avec le pont. Mais le décorateur est spécifiquement une chose d'exécution et est destiné à être alternative à une approche de sous-classement. La force de la décorateur est également que cela vous permet de fournir de nombreuses décorations, alors que mon approche ne fait qu'un à la fois - bien que je puisse envisager un modèle de porte-mixines généralisée pouvant atteindre cela. Encore une fois, de toute façon, c'est un nom de niveau idiome que je recherche - pas de niveau de modèle.


En réalité, rien n'empêche votre idée d'être appliqué de manière récursive: concreteclass * cc = nouvelle implémente > (); , à la condition de dériver à partir des deux interfacea et interfaceb . Cependant, le décorateur signifie enrichir une fonctionnalité existante pendant votre approche, la fonctionnalité n'existe pas auparavant.



1
votes

Ceci est un mixin


4 commentaires

Bien que cela partage certainement certains aspects des mélanges, j'ai délibérément dit cela. À partir de l'article Wikipedia, je suis lié à (Sentez-vous de contredire que - existe-t-il une définition faisant autorité quelque part?) Il est dit: «Un mixin est une classe qui fournit une certaine fonctionnalité à hériter d'une sous-classe, sans être destinée à l'instanciation». Sur les deux comptes, l'idiome dont je parle envolime la situation. C'est la classe générique qui sous-classe la classe spécifique (terminologie gênante) et est destinée à l'instanciation. Peut-être que la classe de base est le mixin, mais ce n'est pas ce dont j'ai besoin du nom.


Je ne suis pas d'accord avec la définition de Wikipedia. Voici un travail académique sur les mixines: Disi.UNIGE.it/Person/lagoriog/jamle a>. Examiner la déclaration: "Exemple de classewithundo = Undo étend l'exemple {}" (à la fin de la deuxième extrait), où annuler est un mixin, semble 100% équivalent à Typef ImplementsRC MyNewType;


Très intéressant. Cela semble correspondre plus fortement. Je ne suis pas sûr que i est d'accord avec cet utilisation de ces sites de mixin, cependant :-) La classe Heir ressemble à un terme plus utile, cependant. Merci pour le lien.


Entre vous et Jonnii, je suis convaincu que c'est toujours un mixin. Merci pour vos commentaires



3
votes

C'est une idée intéressante. Cependant, je ne vais pas vous donner le nom d'un modèle déjà établi ici, sur le contraire, je vais expliquer (un peu) pourquoi je ne pense pas que cela en a déjà une.

Que fait-il ?

C'est un très bon moyen d'éviter l'héritage de diamant redoutant.

car il y a une certaine confusion apparemment sur le but de la méthode, laissez-moi élaborer pourquoi Je pense que c'est son objectif: xxx

maintenant, nous avons ici un problème. Si nous mettons la mise en œuvre de refCompond à droite dans cette classe, il devient une classe de base au lieu d'une interface, et nous devons donc utiliser le héritage virtuel ou les membres de données seront dupliqués (présents dans les deux B et C).

L'idée est donc de différer la mise en œuvre au dernier moment.

Avantages:

  • Pas besoin d'essayer de deviner l'utilisation de B ou C: Héritage virtuel est inutile là-bas.
  • Le compilateur vous rappellera joliment si vous oubliez d'ajouter la mise en œuvre, donc pas besoin de vous inquiéter de cela.

    inconvénient:

    • Mettez le fardeau sur le client: vous feriez mieux de créer une usine pour créer vos objets, en particulier depuis qu'un objet peut implémenter diverses interfaces !!! Notez que cela pourrait être automatisé avec des modèles méta-programmation (plus ou moins) ou peut simplement été fourni par l'auteur de la classe.

      Exemple de fourniture: xxx

      alors quel est le nom?

      Je ne peux pas penser de tout ce qui correspond exactement à cela. Le pont et le décorateur ont été mentionnés, mais c'est tout à fait spécial, et en fait pas non oo-orienté (par exemple, cela ne se produira pas en Java, car vous n'avez pas de multi-héritage), alors je doute que le terme se trouve le terme Dans le livre de Gof.

      En outre, ce n'est pas vraiment le CRTP car il existe une sorte de boucle dans le CRTP (base étant consciente de sa classe dérivée) qui ne se produit pas ici> Nous sommes vraiment strictement linéaires!

      Et puis, ce n'est certainement pas l'idiome PIMPL, qui propose de masquer la mise en œuvre du client lors de l'utilisation d'un modèle pour la mise en œuvre, jetez-la à son visage! (Le modèle pourrait utiliser PIMPL comme détail interne, cependant)

      Je suggère humblement jiti pour juste dans le temps implémentant , qui imite en quelque sorte le titre, mais est plus proche du point que je pense, dérivation ici étant juste un outil plutôt qu'un objectif.

      idée intéressante de toute façon.


1 commentaires

Merci matthieu. Vous semblez certainement avoir saisi le design. Et oui, il s'agit en grande partie d'éviter le problème de héritage de diamant sans héritage virtuel. Jiti est un nom intéressant. Je ne sais pas si c'est vraiment meilleur ou pire que le mien, bien que du moins ait un acronyme plus prononçable ;-)



1
votes

J'envisagerai certainement que ceci soit un mixin, comme ce serait Bruce Eckel ( http://www.artima.com/weblogs/viewpost.jsp?Thread=132988 ).

À mon avis, une des choses qui fait qu'un mixin est que c'est encore une héritage unique, qui est différente de l'utilisation de MI pour atteindre quelque chose de similaire.


1 commentaires

Ok, je suis convaincu. Je voudrais toujours la différencier à partir d'un "standard" Mi Mixin, cependant. Je marquais cela comme la réponse acceptée parce que c'était l'article Eckel qui m'a convaincu, mais techniquement, Itay poussa pour la première fois pour la mixine



1
votes

En regardant votre exemple de comptage de référence, vous pouvez obtenir une certaine joie dans CCOMOBJECT <> Quelle est l'une des classes de plusieurs modèles que ATL contient pour fournir la mise en œuvre d'Iunknown. Il utilise également des classes de politique pour faire varier le comportement. Naturellement, le rapport signal à bruit essaye de google sur le concept de CCOMObject est très faible car il est tellement omniprésent. Cet article de MSDN peut vous donner d'autres "mots-clés" pour faciliter la recherche.

http://msdn.microsoft.com/ EN-US / Bibliothèque / C43H4867 (vs.80) .aspx

[NB: Juste pour être clair - je ne suggère pas qu'il utilise CComObject, je suggère que c'est un autre exemple populaire du même concept et peut donc avoir été référencé dans un livre de motifs ou article]


1 commentaires

Merci, Chris. Je pense que CCOMObject <> est probablement l'un des premiers exemples que j'ai vue de cet idiome utilisé. Je ne me souviens pas de Microsoft en train de vous en faire référence comme un idiome nommé, cependant - et un regard rapide sur l'article lié ne suggère rien de différent.



0
votes

Répondre à ma propre question. Premier signe de folie? - Non, il y avait plusieurs signes avant cela; -)

Quoi qu'il en soit, ça fait si longtemps que je publie à l'origine, je suis de plus en plus une personne différente de toute façon.

J'ai trouvé que je me suis installé sur le nom, mixover . J'ai trouvé cela très bien et peut être considéré comme un raffinement de mixin, plutôt que d'être exclusif au concept plus général.

Je les utilise beaucoup récemment, alors je pensais revenir et mettre à jour ce fil.


0 commentaires