Deklarationen und Definitionen (C++)

Ein C++-Programm besteht aus verschiedenen Entitäten wie Variablen, Funktionen, Typen und Namespaces. Jede dieser Entitäten muss deklariert werden, bevor sie verwendet werden können. Eine Deklaration gibt einen eindeutigen Namen für die Entität zusammen mit Informationen zu seinem Typ und anderen Merkmalen an. In C++ ist der Punkt, an dem ein Name deklariert wird, der Punkt, an dem er für den Compiler sichtbar wird. Sie können nicht auf eine Funktion oder Klasse verweisen, die zu einem späteren Zeitpunkt in der Kompilierungseinheit deklariert wird. Variablen sollten so nah wie möglich vor dem Punkt deklariert werden, an dem sie verwendet werden.

Das folgende Beispiel zeigt einige Deklarationen:

#include <string>

int f(int i); // forward declaration

int main()
{
    const double pi = 3.14; //OK
    int i = f(2); //OK. f is forward-declared
    C obj; // error! C not yet declared.
    std::string str; // OK std::string is declared in <string> header
    j = 0; // error! No type specified.
    auto k = 0; // OK. type inferred as int by compiler.
}

int f(int i)
{
    return i + 42;
}

namespace N {
   class C{/*...*/};
}

In Zeile 5 wird die main Funktion deklariert. In Zeile 7 wird eine const variable namens pi deklariert und initialisiert. In Zeile 8 wird eine ganze Zahl i deklariert und mit dem von der Funktion ferzeugten Wert initialisiert. Der Name f ist aufgrund der Vorwärtsdeklaration in Zeile 3 für den Compiler sichtbar.

In Zeile 9 wird eine Variable mit dem Namen obj des Typs C deklariert. Diese Deklaration löst jedoch einen Fehler aus, da C sie erst später im Programm deklariert wird und nicht vorwärts deklariert wird. Um den Fehler zu beheben, können Sie entweder die gesamte Definition zuvor Cmain verschieben oder eine Vorwärtsdeklaration dafür hinzufügen. Dieses Verhalten unterscheidet sich von anderen Sprachen wie C#. In diesen Sprachen können Funktionen und Klassen vor dem Deklarationspunkt in einer Quelldatei verwendet werden.

In Zeile 10 wird eine Variable mit dem Namen str des Typs std::string deklariert. Der Name std::string ist sichtbar, da er in der stringHeaderdatei eingeführt wird, die in der Quelldatei in Zeile 1 zusammengeführt wird. std ist der Namespace, in dem die string Klasse deklariert wird.

In Zeile 11 wird ein Fehler ausgelöst, da der Name j nicht deklariert wurde. Eine Deklaration muss einen Typ bereitstellen, im Gegensatz zu anderen Sprachen wie JavaScript. In Zeile 12 wird der auto Schlüsselwort (keyword) verwendet, der den Compiler angibt, den Typ basierend k auf dem Wert abzuleiten, mit dem er initialisiert wird. Der Compiler in diesem Fall wählt int für den Typ aus.

Gültigkeitsbereich der Deklaration

Der Name, der durch eine Deklaration eingeführt wird, ist innerhalb des Gültigkeitsbereichs gültig, in dem die Deklaration auftritt. Im vorherigen Beispiel sind die variablen, die innerhalb der main Funktion deklariert sind, lokale Variablen. Sie könnten eine andere Variable deklarieren, die außerhalb von Standard, im globalen Bereich benannt i ist, und es wäre eine separate Entität. Solche Duplizierungen von Namen können jedoch zu Verwirrung und Fehlern von Programmierern führen und sollten vermieden werden. In Zeile 21 wird die Klasse C im Bereich des Namespace Ndeklariert. Die Verwendung von Namespaces trägt dazu bei, Namenskonflikte zu vermeiden. Die meisten C++-Standardbibliotheksnamen werden im std Namespace deklariert. Weitere Informationen zur Interaktion von Bereichsregeln mit Deklarationen finden Sie im Bereich.

Definitionen

Einige Entitäten, einschließlich Funktionen, Klassen, Enumerationen und Konstantenvariablen, müssen sowohl definiert als auch deklariert werden. Eine Definition stellt dem Compiler alle Informationen bereit, die er zum Generieren von Computercode benötigt, wenn die Entität später im Programm verwendet wird. Im vorherigen Beispiel enthält Zeile 3 eine Deklaration für die Funktion f , aber die Definition für die Funktion wird in den Zeilen 15 bis 18 bereitgestellt. In Zeile 21 wird die Klasse C sowohl deklariert als auch definiert (obwohl die Klasse wie definiert nichts tut). Eine Konstantenvariable muss definiert werden, d. h. einem Wert in derselben Anweisung, in der sie deklariert wird. Eine Deklaration eines integrierten Typs, z int . B. automatisch eine Definition, da der Compiler weiß, wie viel Speicherplatz dafür zugewiesen werden soll.

Das folgende Beispiel zeigt Deklarationen, die auch Definitionen sind:

// Declare and define int variables i and j.
int i;
int j = 10;

// Declare enumeration suits.
enum suits { Spades = 1, Clubs, Hearts, Diamonds };

// Declare class CheckBox.
class CheckBox : public Control
{
public:
    Boolean IsChecked();
    virtual int     ChangeState() = 0;
};

Hier sind einige Deklarationen, die keine Definitionen sind:

extern int i;
char *strchr( const char *Str, const char Target );

Typedefs und Using-Anweisungen

In älteren Versionen von C++ wird die typedef Schlüsselwort (keyword) verwendet, um einen neuen Namen zu deklarieren, der ein Alias für einen anderen Namen ist. Der Typ ist z. B std::string . ein anderer Name für std::basic_string<char>. Es sollte offensichtlich sein, warum Programmierer den Typedef-Namen und nicht den tatsächlichen Namen verwenden. In modernen C++ wird die using Schlüsselwort (keyword) bevorzugttypedef, aber die Idee ist identisch: Ein neuer Name wird für eine Entität deklariert, die bereits deklariert und definiert ist.

Elemente statischer Klassen

Statische Klassendatenmember sind diskrete Variablen, die von allen Objekten der Klasse gemeinsam verwendet werden. Da sie freigegeben sind, müssen sie definiert und außerhalb der Klassendefinition initialisiert werden. Weitere Informationen finden Sie unter Klassen.

Externe Deklarationen

Ein C++-Programm kann mehr als eine Kompilierungseinheit enthalten. Um eine Entität zu deklarieren, die in einer separaten Kompilierungseinheit definiert ist, verwenden Sie die extern Schlüsselwort (keyword). Die Informationen in der Deklaration reichen für den Compiler aus. Wenn die Definition der Entität jedoch nicht im Verknüpfungsschritt gefunden werden kann, löst der Linker einen Fehler aus.

In diesem Abschnitt

Speicherklassen
const
constexpr
extern
Initialisierer
Aliasse und Typdefinitionen
using Erklärung
volatile
decltype
Attribute in C++

Siehe auch

Grundlegende Konzepte