2010-06-01 7 views
29

Lors de la compilation sur GCC, j'obtiens l'erreur : spécificateur pur sur la définition de fonction, mais pas lorsque je compile le même code en utilisant VS2005.spécificateur pur sur la fonction-définition

class Dummy { 
    //error: pure-specifier on function-definition, VS2005 compiles 
    virtual void Process() = 0 {}; 
}; 

Mais quand la définition de cette fonction virtuelle pure n'est pas en ligne, cela fonctionne:

class Dummy 
{ 
    virtual void Process() = 0; 
}; 
void Dummy::Process() 
{} //compiles on both GCC and VS2005 

Qu'est-ce que les moyens d'erreur? Pourquoi je ne peux pas le faire en ligne? Est-il légal d'éluder le problème de compilation comme indiqué dans le deuxième exemple de code?

Répondre

24

Ok, je viens d'apprendre quelque chose. Une fonction virtuelle pure doit être déclarée comme suit:


class Abstract 
{ 
public: 
    virtual void pure_virtual() = 0; 
}; 

Il peut avoir un corps, bien qu'il soit illégal d'inclure au moment de la déclaration. Cela signifie que pour avoir un corps, la fonction virtuelle pure doit être définie en dehors de la classe. Notez que même si elle a un corps, la fonction doit toujours être remplacée par toutes les classes concrètes dérivées de Abstract. Ils auraient juste une option pour appeler Abstract::pure_virtual() explicitement s'ils en ont besoin.

Les détails sont here.

+2

Oui, il le devrait, si vous en avez besoin. C'est parfaitement légal d'en avoir un. –

+0

Mais avec un corps ce serait juste une fonction virtuelle. Que devrait faire une fonction virtuelle pure avec un corps ??? –

+1

@Martin Peut-être rien - si vous déclarez un destructeur virtuel pur (par exemple) vous devez lui donner un corps. –

10

Cette syntaxe:

virtual void Process() = 0 {}; 

est pas légal C++, mais est pris en charge par VC++. Exactement pourquoi la norme ne permet pas cela n'a jamais été évident pour moi. Votre deuxième exemple est légal.

4

Les fonctions virtuelles pures en C++ n'ont par définition aucune définition dans la déclaration.

Votre deuxième bloc de code n'évite pas le problème du compilateur. Il met en œuvre une fonction virtuelle pure comme elle était destinée.

La question à se poser est: pourquoi avez-vous besoin de le déclarer purement virtuel si vous avez l'intention d'avoir une implémentation par défaut?

+2

Les fonctions virtuelles pures peuvent avoir une définition. Pensez au destructeur virtuel pur - il DOIT être défini. – Paul

+1

S'il vous plaît éclairer moi dans le but d'un destructeur virtuel pur? –

+1

Vous rendez un destructeur pur lorsque vous ne voulez pas que sa classe soit instanciée et qu'il n'y a pas d'autres candidats PVF. Assez rare, je suis d'accord. –

16

standard C++, 10.4/2:

a function declaration cannot provide both a pure-specifier and a definition

+0

Ceci n'est pas normatif mais provient d'une note. – Columbo

+0

@Columbo Eh bien, conformément au § 6.5.5 des Directives ISO/CEI, les notes de la partie 2 ne doivent pas contenir d'autorisations du tout. Bien que cette note en contienne clairement une, elle m'induit en erreur. GCC et Clang ne permettent toujours pas cela, violent-ils la norme? – Paul

+0

Protip: Lire ma réponse. La note * est * correcte, mais pour 'prouver' celle-ci doit montrer les règles de grammaire. – Columbo

0

Vous pouvez certainement fournir un corps pour la fonction virtuelle pure. Cette fonction sera pointée par cette classe abstraite vtable. Sinon, le même emplacement pointera sur la fonction de déroutement spécifique au compilateur comme __cxa_pure_virtual pour GCC. Il n'y a bien sûr rien à ce sujet dans la norme.

3

C'est grammaticalement sur Rejeté - déclarateur qui peut inclure pur-spécificateurs, à savoir l'élément déclarateur , apparaît seulement dans les déclarations qui ne sont pas des définitions. [Class.mem] :

member-declaration:
         attribute-specifier-seqopt decl-specifier-seqoptmember-declarator-listopt;
         function-definition
         [...]

member-declarator-list:
         member-declarator
         member-declarator-list , member-declarator

member-declarator:
         declarator virt-specifier-seqoptpure-specifieropt
         declarator brace-or-equal-initializeropt
         identifieroptattribute-specifier-seqopt:constant-expression

La grammaire de fonction définition ne comprend pas pur spécificateur, [dcl.fct.def.général]:

function-definition:
     attribute-specifier-seqopt decl-specifier-seqoptdeclarator virt-specifier-seqoptfunction-body

Questions connexes