Je lisais la documentation de Le problème avec héritage publiquement à partir de Pourquoi stimulera-t-on les développeurs, puis le comité a décidé de mettre en œuvre std :: sub_match
std :: paire
sub_match code> est simplement une paire d'itérateurs dans une séquence de caractères, avec quelques fonctions supplémentaires, je peux comprendre qu'il est implémenté avec une paire
code>, mais pourquoi utiliser l'héritage public ? p>
std :: paire
sub_match code>). P>
Sub_Match code> en héritant publiquement à partir de la paire code> au lieu d'utiliser la composition (ou héritage privé avec l'utilisation de déclarations si elles voulaient conserver Accès membre via
premier code> et
second code>)? p>
5 Réponses :
Parce qu'ils n'avaient pas besoin de destructeurs virtuels? ; -) p>
Les destructeurs ne sont pas les seuls membres qui ne vont pas fonctionner correctement: l'opérateur d'affectation et l'échange ne copieront que les membres code> code> et non ceux contenus par sub_match code> (le
correspondant code> boolean notamment).
Les auteurs ont évidemment estimé qu'ils n'avaient pas besoin d'un destructeur virtuel, ou ils auraient fourni un. Mais pourquoi, puisque dans la plupart des cas, le patrimoine public implique la nécessité d'un destructeur virtuel dans la classe de base.
@LUCTOURAILLE Bon point. Clairement, il n'y a pas d'intention que sub_match code> ISA
paire code>.
@Jameskanze: Vous avez raison, la relation "is-a" ne s'applique pas à ces deux classes, le principe de substitution de Liskov n'est pas respecté.
@LUC TOURAILLE: Bien que cela soit plus que raisonnable, de s'attendre à ce que la destruction fonctionne correctement pour des objets polymorphes, je dirais que l'attente d'une affectation ou d'un échange pour faire quoi que ce soit sensible dans un contexte polymorphique demande des problèmes.
@Nicolamusatti: C'est un point juste, qui corrobore en fait le fait que l'héritage est probablement une mauvaise idée ici: paire code> et
sub_match code> sont les deux types avec une sémantique de valeur, qui sont destiné à être copié, assigné, etc. En tant que tel, je ne pense pas que les avoir dans une hiérarchie de classe est un tel design, car il fabrique l'utilisateur de faire preuve de prudence de trancher des problèmes et autres.
Eh bien, la chose est que Sub_Match est i> une paire et rien d'autre, il n'a donc besoin aucune fonctionnalité supplémentaire. En y hérissant de la paire, vous avez un avantage de l'utiliser où une paire est acceptée.
@ Michaelkrelin-Hacker: C'est le point: c'est est i> plus qu'une paire. Il dispose notamment d'un membre code> Boolean correspondant. Et cela ne fonctionne pas partout a code> est accepté (cf. boost.range).
Oui, tu as raison, c'est plus qu'une paire. Je ne sais pas pourquoi paire ne fonctionnerait-il pas où la paire est acceptée, mais cependant.
@Michael: Dans le cas de Boost.Range, il doit s'agir d'un problème de spécialisation du modèle, ce qui ne fonctionne pas très bien avec la hiérarchie de l'héritage. Je dois admettre que cela n'est pas très pertinent pour le sujet, car il s'agit plus d'une faille de conception de modèles.
Si std :: sub_match
std :: paire code>. Ne le faites pas à la maison cependant. P>
L'état n'a rien à voir avec ça. Si vous supprimez un SUB_MATCH CODE> Objet via un
paire <> code> pointeur, c'est un comportement indéfini.
De plus, il a en effet un état propre (un booléen indiquant si le match a été réussi).
C'est une question intéressante. Vraisemblablement, ils considéraient cela en sécurité
Parce que personne ne l'allouerait jamais de façon dynamique une de toute façon. À propos de
Seule façon que vous allez obtenir Notez qu'il n'est pas sûr de garder J'aurais toujours évité l'héritage public. Mais dans ce cas, c'est
pas aussi dangereux que cela semble, car il n'y a vraiment aucune raison.
jamais envie d'allouer de manière dynamique un sub_match code> est comme une valeur de retour
de certaines des fonctions de
basic_regex code> ou en copies d'autres
sub_match code>, et tous ces éléments seront temporaires ou locaux
variables. p>
sub_match code> Objets autour de toute façon, car
ils contiennent des itérateurs dont la vie ... ne semble pas être spécifiée dans
le standard. Jusqu'à ce que l'objet code> match_results code> est réutilisé? Jusqu'à ce que le
chaîne code> opérande à la fonction rempli dans le
match_results code>
l'objet est désttructif? Ou? P>
sub_match code>. p>
Je suis d'accord sur l'allocation dynamique qui ne devrait probablement jamais arriver. Cependant, des problèmes pourraient toujours apparaître avec = code> et
échange code>. Je pensais à Boost.Range par exemple, mais cela ne nécessite pas que des gammes soient assignées ou rapides. Cependant, il est intéressant de noter que Boost.Range algorithmes n'accepte pas
Sub_Match code> ES comme des arguments, mais le font si elles sont manipulées via une référence à une paire code> (catégories de trait> problèmes).
Voici ce que rien de très spécifique à votre question, j'ai peur. P>
Je devinerais que cette décision était un compromis entre réinventer la roue et introduire un peu de risque d'utilisation abusive. Notez que, en général, il n'est pas nécessaire de construire un Regex Code> S doit en dire à ce sujet: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1429.htm#matches_discussions P>
sub_match code>, ils sont renvoyés à partir de la fonction
regex code>. De plus, les paires d'itérateurs sont un moyen très pratique de mettre en œuvre des gammes. P>
Parce que c ++ n'a aucun moyen d'hériter d'une interface sans héritage public. Vous pouvez hériter d'une mise en œuvre avec héritage privé, mais tout est privé. Si vous voulez la même interface qu'un aussi, envisagez cette. Ceci est évidemment un comportement non défini: p> mais est-ce tel: p> Pourquoi est-ce le premier à beaucoup plus de une préoccupation que la seconde? p> std :: paire code>, vous devez être em> a
std :: paire code>.
sub_match code> et
paire code> sont des objets de poids léger (en fonction de leur contenu bien sûr). Ils sont destinés à être copiés ou passés par référence, tout ce qui est sûr à 100%. Il y a peu de raisons de les affecter sur le tas et de les utiliser à travers des pointeurs. Donc, alors que je comprends votre préoccupation, je pense qu'il est peu probable qu'il se produise dans n'importe quel code réel. P> p>
En effet, votre deuxième exemple est (presque) aussi défectueux que le premier, mais c'est parce que vous avez considéré que le membre code> serait public: pourquoi supposeriez-vous qu'une telle encapsulation aussi mauvaise serait utilisée? Et pendant que je conviens que la suppression ne serait probablement jamais une question, je suis en désaccord que le passage par référence est 100% sûr, en raison des autres fonctions de membre non virtuel.
Vous peut i> hériter (pièces) d'une interface publique à l'aide d'une héritage privé: classe SUB_MATCH: paire {Utilisation de paire.First; en utilisant la paire.seconde; bool correspondant; } code>
Si vous souhaitez la même interface qu'un std :: paire code> sans être un, vous pouvez utiliser un héritage privé avec l'utilisation de déclarations et / ou de délégation. Bien sûr, cela reste beaucoup plus de travail pour le développeur de la sous-classe.