Nein, das ist kein String-Ersatz - das wären Makros. Es erstellt einen Alias für den Typ.
typedefs werden gegenüber Makros bevorzugt für benutzerdefinierte Typen, teilweise weil sie die Zeigertypen korrekt codieren können.
s1, s2 und s3 werden alle als char * deklariert, aber s4 wird als char deklariert, was wahrscheinlich nicht die Absicht ist.
A typedef
führt ein Synonym für Typen ein. Es ist kein einfacher String-Ersatz, wie das folgende zeigt:
Der Compiler ist sich auch bewusst, dass es sich um einen Typnamen handelt. Sie können ihn nicht einfach irgendwo platzieren, wo ein Typ nicht erlaubt ist, ohne einen Compilerfehler zu bekommen.
Alle stimmen darin überein, dass es keine Typensubstitution ist, und dass es viel besser ist, als wenn Zeiger in den Mix kommen, aber es gibt auch andere Feinheiten. Insbesondere die Verwendung von typedefs kann die Analyse von Code und die Gültigkeit von Programmen beeinflussen.
Sowohl in C als auch in C ++ werden benutzerdefinierte IDs in verschiedenen Namensräumen gespeichert (nicht im C ++ Sinn, sondern in irgendeiner Art von Identifier-Space). Wenn Sie das Schlüsselwort typedef verwenden, erstellen Sie einen Alias für den Typ im globalen -Namensraum , in dem sich Funktionen befinden.
%Vor%Ein kleiner Unterschied ist hier, dass der Compiler in C ++ zuerst in den globalen Namensraum hineinschaut und wenn er dort nicht gefunden wird, wird er auch in den Namensraum des Typen schauen:
%Vor%Dies bedeutet jedoch nicht, dass die beiden Namespaces zusammengeführt werden, sondern nur, dass die Suche an beiden Stellen erfolgt.
Eine wichtige Unterscheidung ist, dass typedef
s scope hat.
Das Folgende ist ein gängiges Idiom
%Vor% Häufig würde die Konstruktordefinition in einer CPP-Datei mit der Deklaration im Header enthalten sein. Wenn Sie Foo(int x) : Bar(x)
verwenden, besteht eine gute Chance, dass Sie vergessen, den Konstruktor zu aktualisieren, wenn Sie die Klassenhierarchie so ändern, dass Foo- & gt; Wibble- & gt; Bar statt Foo- & gt; Persönlich empfehle ich, das 'geerbte' typedef zu jeder Unterklasse hinzuzufügen.
Siehe hier für weitere Details: Verwenden von "super" in C ++
Mit typedef erstellen Sie einen Alias. Der Compiler ersetzt den Alias durch den korrekten Code.
Wenn Sie schreiben:
%Vor%Der Compiler bekommt:
%Vor%Makros werden vom Präprozessor erstellt und basieren ausschließlich auf Textersetzung. Man könnte also sagen, dass sie ziemlich dumm sind. Der Präprozessor akzeptiert so ziemlich jeden Müll ohne Syntaxprüfung.
Typedefs werden vom Compiler selbst ausgeführt und sie bearbeiten die eigene Typentabelle des Compilers, indem sie einen von Ihnen definierten abgeleiteten Typ hinzufügen. Dies unterliegt einer vollständigen Syntaxprüfung und einem Mechanismus speziell für Typen.
Sie könnten sich vorstellen, dass der Compiler ähnliche "Arbeit" leistet, wenn Sie eine struct
deklarieren. Es gibt dort eine Definition, und der Compiler verwandelt sie in einen Typ in ihrer Typenliste.
Ich finde typedefs machen Funktionssignaturen viel einfacher zu lesen. Angenommen, Sie möchten einen Zeiger auf ein zweidimensionales Array zurückgeben. Hier ist der lesbare Weg:
%Vor%Und so können Sie es ohne typedef machen:
%Vor%Beachten Sie, dass diese Signatur nicht so aussieht wie die erste Version, bei der ein "String-Ersatz" angewendet wurde.
Wenn die C-Deklaratorsyntax nicht so hässlich war (Stroustrup: "Ich betrachte die C-Deklaratorsyntax als einen Versuch, der fehlschlug"), würde typedefs wahrscheinlich nicht so oft verwendet werden wie jetzt.