Namensräume
Varianten
Aktionen

static Member

Von cppreference.com
< cpp‎ | Sprache
 
 
C++ Sprache
Allgemeine Themen
Kontrollfluss
Bedingte Ausführungsaussagen
if
Iterationsanweisungen (Schleifen)
for
Bereichs-for (C++11)
Sprunganweisungen
Funktionen
Funktionsdeklaration
Lambda-Funktionsausdruck
inline-Spezifizierer
Dynamische Ausnahmespezifikationen (bis C++17*)
noexcept-Spezifizierer (C++11)
Ausnahmen
Namensräume
Typen
Spezifizierer
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Speicherdauer-Spezifizierer
Initialisierung
Ausdrücke
Alternative Darstellungen
Literale
Boolesch - Ganzzahl - Gleitkommazahl
Zeichen - String - nullptr (C++11)
Benutzerdefinierte (C++11)
Dienstprogramme
Attribute (C++11)
Typen
typedef-Deklaration
Typalias-Deklaration (C++11)
Umwandlungen
Speicherzuweisung
Klassen
Klassenspezifische Funktionseigenschaften
explicit (C++11)
static

Spezielle Member-Funktionen
Templates
Sonstiges
 
 

Innerhalb einer Klassendefinition deklariert das Schlüsselwort static Member, die nicht an Klasseninstanzen gebunden sind.

Außerhalb einer Klassendefinition hat es eine andere Bedeutung: siehe Speicherdauer.

Inhalt

[bearbeiten] Syntax

Eine Deklaration für einen statischen Member ist eine Member-Deklaration, deren Deklarationsspezifizierer das Schlüsselwort static enthalten. Das Schlüsselwort static erscheint normalerweise vor anderen Spezifizierern (weshalb die Syntax oft informell als static Datenmember oder static Memberfunktion beschrieben wird), kann aber überall in der Spezifizierersequenz erscheinen.

Der Name jedes statischen Datenmembers und jeder statischen Memberfunktion muss sich vom Namen der enthaltenden Klasse unterscheiden.

[bearbeiten] Erklärung

Statische Member einer Klasse sind nicht mit Objekten der Klasse verbunden: Sie sind unabhängige Variablen mit statischer oder Thread(seit C++11) Speicherdauer oder normale Funktionen.

Das Schlüsselwort static wird nur mit der Deklaration eines statischen Members, innerhalb der Klassendefinition, aber nicht mit der Definition dieses statischen Members verwendet.

class X { static int n; }; // declaration (uses 'static')
int X::n = 1;              // definition (does not use 'static')

Die Deklaration innerhalb des Klassenkörpers ist keine Definition und darf den Member als vom unvollständigen Typ deklarieren (außer void), einschließlich des Typs, in dem der Member deklariert wird.

struct Foo;
 
struct S
{
    static int a[]; // declaration, incomplete type
    static Foo x;   // declaration, incomplete type
    static S s;     // declaration, incomplete type (inside its own definition)
};
 
int S::a[10]; // definition, complete type
struct Foo {};
Foo S::x;     // definition, complete type
S S::s;       // definition, complete type

Wenn die Deklaration jedoch die Spezifizierer constexpr oder inline(seit C++17) verwendet, muss der Member als vollständiger Typ deklariert werden.

(seit C++11)

Um auf einen statischen Member m der Klasse T zuzugreifen, können zwei Formen verwendet werden: qualifizierter Name T::m oder ein Member-Zugriffs-Ausdruck E.m oder E->m, wobei E ein Ausdruck ist, der zu T bzw. T* evaluiert. Wenn sich im selben Klassengültigkeitsbereich, ist die Qualifizierung unnötig.

struct X
{
    static void f(); // declaration
    static int n;    // declaration
};
 
X g() { return X(); } // some function returning X
 
void f()
{
    X::f();  // X::f is a qualified name of static member function
    g().f(); // g().f is member access expression referring to a static member function
}
 
int X::n = 7; // definition
 
void X::f() // definition
{
    n = 1; // X::n is accessible as just n in this scope
}

Statische Member unterliegen den Regeln für den Zugriff auf Klassenmember (private, protected, public).

[bearbeiten] Statische Member-Funktionen

Statische Member-Funktionen sind nicht mit einem Objekt verbunden. Beim Aufruf haben sie keinen this-Zeiger.

Statische Member-Funktionen können nicht virtual, const, volatile oder Referenz-qualifiziert sein.

Die Adresse einer statischen Member-Funktion kann in einem regulären Funktionszeiger gespeichert werden, aber nicht in einem Member-Funktionszeiger.

[bearbeiten] Statische Datenmember

Statische Datenmember sind nicht mit einem Objekt verbunden. Sie existieren, auch wenn keine Objekte der Klasse definiert wurden. Es gibt nur eine Instanz des statischen Datenmembers im gesamten Programm mit statischer Speicherdauer, es sei denn, das Schlüsselwort thread_local wird verwendet, in diesem Fall gibt es ein solches Objekt pro Thread mit Thread-Speicherdauer(seit C++11).

Statische Datenmember können nicht mutable sein.

Statische Datenmember einer Klasse im Namespace-Gültigkeitsbereich haben eine externe Bindung, wenn die Klasse selbst eine externe Bindung hat (kein Member eines namenlosen Namespace). Lokale Klassen (innerhalb von Funktionen definierte Klassen) und namenlose Klassen, einschließlich Member-Klassen von namenlosen Klassen, können keine statischen Datenmember haben.

Ein statischer Datenmember kann inline deklariert werden. Ein Inline-statischer Datenmember kann in der Klassendefinition definiert und mit einem Initialisierer versehen werden. Er benötigt keine Definition außerhalb der Klasse.

struct X
{
    inline static int fully_usable = 1; // No out-of-class definition required, ODR-usable
    inline static const std::string class_name{"X"}; // Likewise
 
    static const int non_addressable = 1; // C.f. non-inline constants, usable
                                          // for its value, but not ODR-usable
    // static const std::string class_name{"X"}; // Non-integral declaration of this
                                                 // form is disallowed entirely
};
(seit C++17)

[bearbeiten] Konstante statische Member

Wenn ein statischer Datenmember vom ganzzahligen oder Aufzählungstyp als const (und nicht als volatile) deklariert wird, kann er mit einem Initialisierer initialisiert werden, bei dem jeder Ausdruck ein konstanter Ausdruck ist, direkt innerhalb der Klassendefinition.

struct X
{
    const static int n = 1;
    const static int m{2}; // since C++11
    const static int k;
};
const int X::k = 3;

Wenn ein statischer Datenmember vom LiteralType als constexpr deklariert wird, muss er mit einem Initialisierer initialisiert werden, bei dem jeder Ausdruck ein konstanter Ausdruck ist, direkt innerhalb der Klassendefinition.

struct X
{
    constexpr static int arr[] = { 1, 2, 3 };        // OK
    constexpr static std::complex<double> n = {1,2}; // OK
    constexpr static int k; // Error: constexpr static requires an initializer
};
(seit C++11)

Wenn ein const nicht-inline(seit C++17) statischer Datenmember oder ein constexpr statischer Datenmember(seit C++11)(bis C++17) einer ODR-Nutzung unterliegt, ist eine Definition im Namespace-Gültigkeitsbereich immer noch erforderlich, aber sie kann keinen Initialisierer haben.

Ein constexpr statischer Datenmember ist implizit inline und muss nicht im Namespace-Gültigkeitsbereich neu deklariert werden. Diese Neudeklaration ohne Initialisierer (früher erforderlich) ist immer noch zulässig, aber veraltet.

(seit C++17)
struct X
{
    static const int n = 1;
    static constexpr int m = 4;
};
 
const int *p = &X::n, *q = &X::m; // X::n and X::m are ODR-used
const int X::n;             // … so a definition is necessary
constexpr int X::m;         // … (except for X::m in C++17)

[bearbeiten] Schlüsselwörter

static

[bearbeiten] Fehlerberichte

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
CWG 194 C++98 (statische) Member-Funktionsnamen können identisch mit dem Klassennamen sein Namensbeschränkung hinzugefügt (einschließlich
nicht-statische Member-Funktionen)

[bearbeiten] Referenzen

  • C++23 Standard (ISO/IEC 14882:2024)
  • 11.4.9 Statische Member [class.static]
  • C++20 Standard (ISO/IEC 14882:2020)
  • 11.4.8 Statische Member [class.static]
  • C++17 Standard (ISO/IEC 14882:2017)
  • 12.2.3 Statische Member [class.static]
  • C++14 Standard (ISO/IEC 14882:2014)
  • 9.4 Statische Member [class.static]
  • C++11 Standard (ISO/IEC 14882:2011)
  • 9.4 Statische Member [class.static]
  • C++98 Standard (ISO/IEC 14882:1998)
  • 9.4 Statische Member [class.static]

[bearbeiten] Siehe auch