web-dev-qa-db-de.com

Überlegenheit von unbenanntem Namespace gegenüber statischem?

Wie sind unbenannte Namespaces dem Schlüsselwort static überlegen?

112
Nawaz

Sie beziehen sich im Grunde auf den Abschnitt $ 7.3.1.1/2 aus dem C++ Standard,

Die Verwendung des Schlüsselworts static ist veraltet, wenn Objekte in einem Namespace-Bereich deklariert werden. Der unbenannte Namespace bietet eine überlegene Alternative.

Unbenannter Namespace ist statischen Schlüsselwörtern überlegen, vor allem, weil das Schlüsselwort static nur für die Variablen Deklarationen und Funktionen gilt, nicht für die benutzerdefinierten Typen.

Der folgende Code ist in C++ gültig

   //legal code
   static int sample_function() { /* function body */ }
   static int sample_variable;

Dieser Code ist jedoch NICHT gültig:

   //illegal code
   static class sample_class { /* class body */ };
   static struct sample_struct { /* struct body */ };

Also die Lösung ist, unbenannter Namespace, was das ist,

   //legal code
   namespace 
   {  
        class sample_class { /* class body */ };
        struct sample_struct { /* struct body */ };
   }

Hoffe, es erklärt, warum unnamed-namespace ist static überlegen.

Beachten Sie außerdem, dass die Verwendung des statischen Schlüsselworts veraltet ist, wenn Objekte in einem Namespace-Bereich deklariert werden (gemäß Standard).

116
Nawaz

In diesem Zusammenhang gibt es ein interessantes Problem:

Angenommen, Sie verwenden das Schlüsselwort static oder das unbenannte namespace, um eine Funktion innerhalb des Moduls (Übersetzungseinheit) zu erstellen, da diese Funktion vom Modul intern verwendet werden soll und außerhalb des Moduls nicht zugänglich ist. (Unbenanntes namespaces hat den Vorteil, dass neben Funktionen auch interne Daten- und Typdefinitionen möglich sind).

Mit der Zeit wird die Quelldatei der Implementierung Ihres Moduls größer und Sie möchten sie in mehrere separate Quelldateien aufteilen, um den Code besser zu organisieren, die Definitionen schneller zu finden und unabhängig kompiliert zu werden.

Aber jetzt haben Sie ein Problem: Diese Funktionen können nicht länger static für das Modul sein, da static sich nicht auf das Modul bezieht, sondern auf das - Quelldatei (Übersetzungseinheit). Sie müssen sie als nicht -static definieren, damit von anderen Teilen (Objektdateien) dieses Moduls aus auf sie zugegriffen werden kann. Dies bedeutet aber auch, dass sie nicht länger für das Modul verborgen/privat sind: Da sie eine externe Verknüpfung haben, können sie von anderen Modulen aus aufgerufen werden, was nicht Ihre ursprüngliche Absicht war.

Unbenanntes namespace würde dieses Problem ebenfalls nicht lösen, da es auch für eine bestimmte Quelldatei (Übersetzungseinheit) definiert ist und von außen nicht zugegriffen werden kann.

Es wäre großartig, wenn man spezifizieren könnte, dass einige namespaceprivate sind, das heißt, was auch immer darin definiert ist, soll intern von dem Modul verwendet werden, zu dem es gehört. Aber natürlich hat C++ kein Konzept wie "Module", sondern nur "Übersetzungseinheiten", die eng an die Quelldateien gebunden sind.

6
SasQ

Der C++ Standard liest in Abschnitt 7.3.1.1 Unbenannte Namespaces, Absatz 2:

Die Verwendung des statischen Schlüsselworts ist veraltet, wenn Objekte in einem Namespace-Bereich deklariert werden. Der unbenannte Namespace bietet eine überlegene Alternative.

Statisch gilt nur für Namen von Objekten, Funktionen und anonymen Vereinigungen, nicht für Typdeklarationen.

6
Salgar