2014-02-19 10 views
6

Was ist der Unterschied zwischen den beiden Methoden?Eine Variable mit dem Schlüsselwort "class" deklarieren vs Eine ohne Schlüsselwort "class" in den Funktionssignaturen deklarieren

Manchmal, wenn ich kompilieren-Zeit Fehler beschweren, dass der Compiler nicht erkennt, einige Klassenarten in Funktionssignaturen, wenn ich das Schlüsselwort "Klasse" vor den jeweiligen Variablen hinzufügen, kann es immer diese Art von lösen Kompilierungsfehler

Zum Beispiel, wenn der Compiler nicht den Typ Kunden in

void recv(Client * c) 

dann erkennt, wenn ich es ändern zu

void recv(class Client * c) 

das Problem gelöst ist.

Es tut mir leid, dass ich mir kein konkretes Beispiel einfallen lassen kann, da ich diese Frage zufällig erhielt.

+0

Nie davon gehört. Können Sie einen [SSCCE] (http://sscce.org/) angeben, der diesen Fehler anzeigt? – delnan

Antwort

12

Die Schlüsselwortklasse struct, enum in einer Typparameterdeklaration wird elaborated type specifier genannt. Es führt den neuen Typ in den Bereich ein, in dem die Funktion deklariert ist. Es ähnelt der Vorwärtsdeklaration.

Es gibt auch eine andere Verwendung einer solchen Deklaration. Wenn beispielsweise ein Name eines Objekts oder eines Funktionsnamens eine Klasse oder eine Enumeration mit demselben Namen verbirgt. Zum Beispiel

struct A {}; 

A A; // now A is seen as an identifier of the object 

void f(struct A); 
+0

Also in dieser Situation brauchen wir das Schlüsselwort struct in der Signatur der Funktion f, um A von dem in der zweiten Zeile deklarierten Variablennamen A zu unterscheiden. –

+0

@phresnel Ja, Sie haben Recht. –

1

In diesem Fall

void recv(Client * c) 

Compiler sucht Erklärung Client. Wenn es nicht finden kann, wird es einen Fehler geben. Sie können es durch Vorwärtsdeklaration lösen als

class Client; 
void recv(Client * c) 

folgenden gezeigt Obwohl ich nie zweiten Fall gesehen habe, aber es sieht so aus, dass auch hier die Klasse Client zu erklären.

1

Wenn Sie Ihren Parameter mit class voranstellen müssen, bedeutet dies, dass der Compiler noch keine Klasse namens Client kennt. Nehmen Sie das folgende erfundene Beispiel:

int main(int argc, char *argv[]) 
{ 
    MyClass m; 

    return 0; 
} 

class MyClass 
{ 
}; 

Da MyClass nach der Hauptfunktion deklariert ist, ist die Hauptfunktion keine Kenntnis von der Klasse aufgerufen MyClass wenn er versucht, die Variable m, und Ihr Programm erstellen würde sich weigern, zu kompilieren.

Um dies zu lösen, würden Sie in der Regel eine Vorwärts-Deklaration verwenden:

class MyClass; // <-- Forward declare MyClass. 

int main(int argc, char *argv[]) 
{ 
    MyClass m; 

    return 0; 
} 

class MyClass 
{ 
}; 

In Ihrem Fall die Verwendung des class Schlüsselwort vor dem Typ des Funktionsparameters im Wesentlichen nach vorne für Sie die Klassennamen zu deklarieren.

+0

also bedeutet das, dass ich am Anfang der Datei auch den forward deklarierten class Client haben könnte, ohne elaborated type specifier in der Funktionssignatur verwenden zu müssen, wie ich es oben getan habe? –

+0

@takwing - Ja, ich würde es erwarten. –

1

Der Compiler muss den Typ des Funktionsparameters kennen. Da Sie offensichtlich keine Definition angeben, z. B. indem Sie den Header Client einbeziehen, müssen Sie eine Forward-Deklaration angeben.Das ist, was Sie im zweiten Beispiel tun (auf eine ungewöhnliche Weise), so dass der Compiler weiß, dass der Client eine Klasse ist. Da Sie nur einen Zeiger verwenden, genügt die Deklaration und Sie brauchen die Definition an dieser Stelle nicht.

Verwandte Themen