2010-06-01 17 views
29

Podczas kompilacji w GCC otrzymuję błąd : czystego specyfikatora w definicji funkcji, ale nie wtedy, gdy kompiluję ten sam kod przy użyciu VS2005.czysty specyfikator w definicji funkcji

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

Ale gdy określenie tej czystej funkcji wirtualnej nie jest inline, to działa:

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

Co środki błędach? Dlaczego nie mogę tego zrobić inline? Czy można omijać problem z kompilacją, jak pokazano w drugim przykładzie kodu?

Odpowiedz

24

Ok, właśnie dowiedziałem się czegoś. Funkcja czysto wirtualna musi być zadeklarowana w następujący sposób:


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

Może mieć korpus, chociaż umieszczenie go w miejscu zgłoszenia jest bezprawne. Oznacza to, że aby mieć ciało, czysta wirtualna funkcja musi być zdefiniowana poza klasą. Zwróć uwagę, że nawet jeśli ma on treść, funkcja musi być nadal nadpisywana przez konkretne klasy pochodzące z Abstract. Po prostu będą musieli zadzwonić pod numer Abstract::pure_virtual(), jeśli będą tego potrzebować.

Szczegóły są here.

+2

Tak, powinien, jeśli jej potrzebujesz. Posiadanie takiego jest całkowicie legalne. –

+0

Ale z ciałem byłaby to tylko funkcja wirtualna. Co powinna zrobić czysta wirtualna funkcja z ciałem? –

+1

@Martin Prawdopodobnie nic - jeśli zadeklarujesz czysty wirtualny destruktor (na przykład), musisz podać mu ciało. –

10

Ta składnia:

virtual void Process() = 0 {}; 

nie jest C++ prawny, ale jest obsługiwany przez VC++. Dokładnie dlaczego Standard nie pozwala na to nigdy nie było dla mnie oczywiste. Twój drugi przykład jest legalny.

4

Czyste funkcje wirtualne w C++ z definicji nie mają definicji w deklaracji.

You drugi blok kodu nie jest unikanie problemu kompilatora. Wdraża czystą wirtualną funkcję w sposób, w jaki był przeznaczony.

pytanie zadać jest, dlaczego trzeba zadeklarować to czysto wirtualne, jeśli masz zamiar mieć implementację domyślną?

+2

Czyste funkcje wirtualne mogą mieć definicję. Pomyśl o czystym wirtualnym destruktorze - MUSI być zdefiniowany. – Paul

+1

Proszę oświecić mnie w celu czystego wirtualnego destruktora? –

+1

Czynisz destruktor, gdy nie chcesz, aby jego klasa została utworzona i nie ma innych kandydatów do PVF. Całkiem rzadki wymóg, zgadzam się. –

16

C++ Standard, 10,4/2:

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

+0

Nie jest to normatywne, ale pochodzi z notatki. – Columbo

+0

@ Columbo Cóż, zgodnie z § 6.5.1 Dyrektyw ISO/IEC Część 2 uwagi nie zawierają w ogóle uprawnień. Chociaż ta uwaga wyraźnie zawiera jedną, która wprowadza mnie w błąd. Nadal nowoczesne GCC i Clang nie pozwalają na to, czy naruszają standard? – Paul

+0

Protip: Przeczytaj moją odpowiedź. Notatka * jest * poprawna, ale aby "udowodnić", ta musi pokazać zasady gramatyki. – Columbo

0

Można oczywiście stworzenie zespołu do czystej funkcji wirtualnej. Ta funkcja będzie wskazywana przez tę abstrakcyjną klasę vtable. W przeciwnym razie ten sam slot będzie wskazywał na specyficzną dla kompilatora funkcję pułapki, taką jak __cxa_pure_virtual dla GCC. Nie ma w tym oczywiście nic w standardzie.

3

to gramatically zabronione - w declarator który może zawierać Pure-specyfikacje dotyczące tj członków declarator pojawia się tylko w zgłoszeniach, które nie są definicje. [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

Gramatyka funkcji rozdzielczości nie zawiera Pure-specyfikator, [dcl.fct.def.ogólne]:

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

Powiązane problemy