65 votes

Les fonctions virtuelles pures peuvent ne pas avoir de définition en ligne. Pourquoi?

Des fonctions virtuelles pures sont celles des fonctions membres qui sont virtuels et ont le pur-spécificateur ( = 0; )

La Clause 10.4 paragraphe 2 de C++03 nous dit ce qu'est une classe abstraite est et, comme une note côté, le suivant:

[Note: une déclaration de fonction ne peut pas fournir à la fois un pur-spécificateur et une définition -la note de fin] [Exemple:

struct C {
virtual void f() = 0 { }; // ill-formed
};

fin de l'exemple]

Pour ceux qui ne sont pas très familiers avec le problème, veuillez noter que les fonctions virtuelles pures peuvent avoir des définitions , mais la clause ci-dessus interdit de telles définitions apparaissent en ligne (lexicalement dans la classe). (Pour l'utilisation de la définition des fonctions virtuelles pures, vous pouvez voir, par exemple, ce GotW)

Maintenant, pour tous les autres types et les types de fonctions qu'il est autorisé à fournir une définition de classe, et cette restriction semble à première vue absolument artificielle et inexplicable. Venez pour penser à elle, c'est sur la deuxième et les suivantes regards :) Mais je crois que la restriction ne serait pas là s'il n'y avait pas de raison particulière pour que.

Ma question est: est-ce quelqu'un connais les raisons? Bon suppositions sont également les bienvenus.

Notes:

  • MSVC ne permettent PVF pour avoir inline définitions. Donc ne soyez pas surpris :)
  • le mot - inline dans cette question ne fait pas référence à l' inline mot-clé. Il est censé signifier lexicalement dans la classe

54voto

Cheers and hth. - Alf Points 59647

Dans le fil “Pourquoi la fonction virtuelle pure est initialisé à 0?” Jerry Cercueil fourni cette citation de Bjarne Stroustrup de La Conception Et de l'Évolution de C++, de l'article 13.2.3, où j'ai ajouté un peu de l'accent de la partie, je pense, est pertinente:

Les curieux =0 de la syntaxe qui a été choisi l'alternative évidente de l'introduction de un nouveau mot-clé pur ou abstrait parce que à l'époque, je n'ai vu aucune chance d'obtenir un nouveau mot-clé accepté. Avais-Je suggéré pure, la Version 2.0 aurait livré sans les classes abstraites. Étant donné le choix entre une belle syntaxe et les classes abstraites, j'ai choisi abstrait des classes. Plutôt que de risquer de retard et engager de certains combats plus pure, j'ai utilisé la tradition de C et de C++ convention d'utilisation de 0 à représenter "n'y est pas." L' =0 de la syntaxe correspond à à mon avis, un corps de la fonction est la initialiseur pour une fonction et aussi avec l' (simpliste, mais généralement suffisant) vue de l'ensemble des fonctions virtuelles la mise en œuvre d'un vecteur de des pointeurs de fonction. [ ... ]

Ainsi, lors du choix de la syntaxe Bjarne était la pensée d'un corps de fonction comme une sorte de initialiseur de la partie de la déclaration, et =0 comme une forme alternative de l'initialiseur, qui a indiqué “pas de corps” (ou dans ses mots, “pas là”).

Il va de soi que l'on ne peut pas indiquer “pas là” et avoir un corps qui conceptuelle de l'image.

Ou, toujours dans cette conceptuel de l'image, ayant deux initialiseurs.

Maintenant, c'est aussi loin que mes pouvoirs télépathiques, google-foo et doux au raisonnement va. J'ai supposer que personne n'a été Assez Intéressé™ pour formuler une proposition de la commission sur le fait d'avoir ce purement syntaxique restriction levée, et le suivi avec tout le travail que cela implique. Ainsi, il est toujours de cette façon.

8voto

AProgrammer Points 31212

Vous ne devriez pas avoir assez de foi dans la commission de normalisation. Pas tout a une raison profonde à l'expliquer. Quelque chose sont donc tout simplement parce que à la première personne n'a pensé autrement et après personne n'a pensé que changer c'est assez important (je pense que c'est le cas ici); pour des choses assez vieux, il pourrait même être un artefact de la première mise en œuvre. Certains sont le résultat de l'évolution -- il y a une raison profonde à la fois, mais la raison a été retiré et que la décision n'était pas reconsidéré à nouveau (il pourrait aussi être le cas ici, où la décision initiale a été parce que toute définition de la fonction pure était interdit). Certains sont le résultat de la négociation entre les différents POV et le résultat manque de cohérence, mais ce manque a été jugé nécessaire de parvenir à un consensus.

7voto

Tony D Points 43962

Bon devine... eh bien, compte tenu de la situation:

  • il est légal pour déclarer la fonction en ligne et de fournir explicitement inline corps (en dehors de la classe), donc il n'y a clairement pas d'objection à la seule conséquence pratique d'être déclaré à l'intérieur de la classe.
  • Je ne vois pas le potentiel des ambiguïtés ou des conflits introduit dans la grammaire, donc pas de raison logique de l'exclusion de définitions de fonction in situ.

Ma conjecture: l'utilisation pour les corps de fonctions virtuelles pures a été réalisé d'après l' = 0 | { ... } de la grammaire a été formulée, et la grammaire n'était tout simplement pas révisé. Il est utile de considérer qu'il y a beaucoup de propositions pour la langue changements / améliorations - y compris ceux pour faire des choses comme ce qui est plus logique et cohérent - mais le nombre qui sont ramassé par quelqu'un et écrite sous forme de propositions formelles est beaucoup plus petit, et le nombre de celles que le Comité a le temps d'examiner, et il croit que le compilateur vendeurs seront prêts à mettre en œuvre, est beaucoup plus petite encore. Ce genre de choses ont besoin d'un champion, et peut-être vous êtes la première personne à voir un problème. Pour avoir une idée de ce processus, découvrez http://www2.research.att.com/~bs/evol-issues.html.

2voto

towi Points 5192

Bon suppositions sont les bienvenus, vous dites?

Je pense que l' = 0 à la déclaration , c'est d'avoir la mise en œuvre dans l'esprit. Il est probable que cette définition signifie, que vous obtenez un NULL entrée dans le RTTI de l' vtbl de la classe de l'information-l'emplacement au moment de l'exécution adresses des fonctions membres d'une classe sont stockées.

Mais en réalité, lorsqu'une définition de la fonction dans votre *.cpp le fichier, vous introduisez un nom dans le fichier objet pour l'éditeur de liens: Une adresse dans l' *.o le fichier où trouver une fonction spécifique.

La base de l'éditeur de liens ne puis besoin de savoir sur le C++ plus. Il peut tout lier ensemble, même si vous avez déclaré comme = 0.

Je pense que j'ai lu que c'est possible ce que vous avez décrit, bien que j'ai oublié le comportement :-)...

0voto

CashCow Points 18388

Laissant les destructeurs de côté, les implémentations de fonctions virtuelles pures sont une chose étrange, parce qu'ils n'obtiennent jamais appelé de manière naturelle. c'est à dire si vous avez un pointeur ou une référence à votre classe de Base de l'objet sous-jacent sera toujours certains Dérivés qui remplace la fonction, et qui sera toujours appelée.

La seule façon de réellement obtenir la mise en œuvre est appelée à l'aide de la Base::func() la syntaxe à partir de l'un des dérivés de la classe des surcharges.

De ce fait, à certains égards, en fait une meilleure cible pour l'in-lining, au point où le compilateur veut l'invoquer, il est toujours clair de la surcharge est appelé.

Aussi, si implémentations de fonctions virtuelles pures ont été interdits, il y aurait une solution évidente de certains autres (probablement protégé) non-fonction virtuelle dans la classe de Base que vous pouvez simplement appeler régulièrement à partir de votre fonction dérivée. Bien sûr, le champ d'application serait moins limitée que vous pourriez l'appeler à partir de n'importe quelle fonction.

(En passant, je suis sous l'hypothèse que l' Base::f() ne peut être appelée avec cette syntaxe de Derived::f() et non pas à partir d' Derived::anyOtherFunc(). Je suis bon avec cette hypothèse?).

Virtuelle Pure destructeurs sont une autre histoire, dans un sens. Il est utilisé comme une technique tout simplement pour éviter que quelqu'un crée une instance de la classe dérivée sans qu'il y ait des fonctions virtuelles pures ailleurs.

La réponse à la question du "pourquoi" il n'est pas permis est vraiment tout simplement parce que le comité de normalisation a dit oui, mais ma réponse jette une certaine lumière sur ce que l'on cherche à atteindre de toute façon.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X