Namespaces
Variants

Class declaration

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Class/struct types
Union types

Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Klassen sind benutzerdefinierte Typen, definiert durch einen Klassen-Spezifizierer, der in der decl-specifier-seq der Deklarations -Syntax erscheint.

Inhaltsverzeichnis

Syntax

Die Klassenspezifikation hat die folgende Syntax:

class-key attr  (optional) class-head-name class-property-specs  (optional) base-clause  (optional)
{ member-specification }
(1)
class-key attr  (optional) base-clause  (optional)
{ member-specification }
(2)
1) Benannte Klassendefinition
2) Unbenannte Klassendefinition
class-key - einer von class , struct und union . Die Schlüsselwörter class und struct sind identisch, außer für den Standard- Mitgliedszugriff und den Standard- Basisklassenzugriff . Wenn es union ist, führt die Deklaration einen Union-Typ ein.
attr - (seit C++11) beliebig viele Attribute , kann alignas Spezifizierer enthalten
class-head-name - der Name der zu definierenden Klasse, optional qualifiziert
class-property-specs - Eine Liste der folgenden Spezifizierer, jeder Spezifizierer ist in jeder Sequenz höchstens einmal erlaubt.
Spezifizierer Wirkung
final
(seit C++11)
Spezifiziert, dass die Klasse nicht abgeleitet werden kann
trivially_relocatable_if_eligible
(seit C++26)
Markiert die Klasse als trivial relozierbar, wenn berechtigt
replaceable_if_eligible
(seit C++26)
Markiert die Klasse als ersetzbar, wenn berechtigt
base-clause - Liste von einer oder mehreren Basisklassen und dem für jede verwendeten Vererbungsmodell (siehe abgeleitete Klasse )
member-specification - Liste von Zugriffsspezifizierern, Mitgliedsobjekt- und Mitgliedsfunktionsdeklarationen und -definitionen ( siehe unten )

Vorwärtsdeklaration

Eine Deklaration der folgenden Form

class-key attr identifier ;

Deklariert einen Klassentyp, der später in diesem Gültigkeitsbereich definiert wird. Bis die Definition erscheint, hat dieser Klassenname unvollständigen Typ . Dies erlaubt Klassen, die sich gegenseitig referenzieren:

class Vector; // Vorwärtsdeklaration
class Matrix
{
    // ...
    friend Vector operator*(const Matrix&, const Vector&);
};
class Vector
{
    // ...
    friend Vector operator*(const Matrix&, const Vector&);
};

und wenn eine bestimmte Quelldatei nur Zeiger und Referenzen auf die Klasse verwendet, ermöglicht dies die Reduzierung von #include Abhängigkeiten:

// In MyStruct.h
#include <iosfwd> // enthält Vorwärtsdeklaration von std::ostream
struct MyStruct
{
    int value;
    friend std::ostream& operator<<(std::ostream& os, const S& s);
    // Definition bereitgestellt in MyStruct.cpp Datei, die #include <ostream> verwendet
};

Wenn eine Vorwärtsdeklaration im lokalen Gültigkeitsbereich erscheint, verdeckt sie die zuvor deklarierte Klasse, Variable, Funktion und alle anderen Deklarationen desselben Namens, die in umschließenden Gültigkeitsbereichen erscheinen können:

struct s { int a; };
struct s; // tut nichts (s ist bereits in diesem Gültigkeitsbereich definiert)
void g()
{
    struct s; // Vorwärtsdeklaration einer neuen, lokalen Struktur "s"
              // dies verdeckt die globale Struktur s bis zum Ende dieses Blocks
    s* p; // Zeiger auf lokale Struktur s
    struct s { char* p; }; // Definition der lokalen Struktur s
}

Beachten Sie, dass ein neuer Klassenname auch durch einen elaborated type specifier eingeführt werden kann, der als Teil einer anderen Deklaration erscheint, aber nur wenn name lookup keine zuvor deklarierte Klasse mit demselben Namen finden kann.

class U;
namespace ns
{
    class Y f(class T p); // deklariert Funktion ns::f und deklariert ns::T und ns::Y
    class U f(); // U bezieht sich auf ::U
    // kann Zeiger und Referenzen auf T und Y verwenden
    Y* p;
    T* q;
}

Memberspezifikation

Die Memberspezifikation, oder der Body einer Klassendefinition, ist eine in geschweifte Klammern eingeschlossene Sequenz einer beliebigen Anzahl der folgenden Elemente:

1) Elementdeklarationen der Form
attr  (optional) decl-specifier-seq  (optional) member-declarator-list  (optional) ;
attr - (seit C++11) beliebige Anzahl von Attributen
decl-specifier-seq - Sequenz von Spezifizierern . Nur optional in den Deklarationen von Konstruktoren, Destruktoren und benutzerdefinierten Typumwandlungsfunktionen
member-declarator-list - ähnlich einer Init-Deklarator-Liste , erlaubt aber zusätzlich Bitfeld-Deklarationen , Pure-Spezifizierer und Virt-Spezifizierer ( override oder final ) (seit C++11) und erlaubt keine direkte Nicht-Listen-Initialisierungssyntax .

Diese Deklaration kann statische und nicht-statische Datenelemente und Elementfunktionen , Element- Typdefinitionen , Element- Aufzählungen sowie geschachtelte Klassen deklarieren. Es kann sich auch um eine Friend-Deklaration handeln.

class S
{
    int d1;             // non-static data member
    int a[10] = {1, 2}; // non-static data member with initializer (C++11)
    static const int d2 = 1; // static data member with initializer
    virtual void f1(int) = 0; // pure virtual member function
    std::string d3, *d4, f2(int); // two data members and a member function
    enum { NORTH, SOUTH, EAST, WEST };
    struct NestedS
    {
        std::string s;
    } d5, *d6;
    typedef NestedS value_type, *pointer_type;
};
2) Funktionsdefinitionen, die sowohl Member-Funktionen als auch Friend-Funktionen deklarieren und definieren. Ein Semikolon nach einer Member-Funktionsdefinition ist optional. Alle Funktionen, die innerhalb eines Klassenkörpers definiert sind, sind automatisch inline , es sei denn, sie sind an ein benanntes Modul gebunden (seit C++20) .
class M
{
    std::size_t C;
    std::vector<int> data;
public:
    M(std::size_t R, std::size_t C) : C(C), data(R*C) {} // constructor definition
    int operator()(std::size_t r, std::size_t c) const // member function definition
    {
        return data[r * C + c];
    }
    int& operator()(std::size_t r, std::size_t c) // another member function definition
    {
        return data[r * C + c];
    }
};
3) Zugriffsspezifizierer public: , protected: , und private:
class S
{
public:
    S();          // public constructor
    S(const S&);  // public copy constructor
    virtual ~S(); // public virtual destructor
private:
    int* ptr; // private data member
};
4) Using-Deklarationen :
class Base
{
protected:
    int d;
};
class Derived : public Base
{
public:
    using Base::d;    // mache Bases geschütztes Mitglied d zu einem öffentlichen Mitglied von Derived
    using Base::Base; // erbe alle Konstruktoren der Basisklassen (C++11)
};
5) static_assert Deklarationen:
template<typename T>
struct Foo
{
    static_assert(std::is_floating_point<T>::value, "Foo<T>: T must be floating point");
};
6) Deklarationen von Member-Templates :
struct S
{
    template<typename T>
    void f(T&& n);
    template<class CharT>
    struct NestedS
    {
        std::basic_string<CharT> s;
    };
};
7) Alias-Deklarationen :
template<typename T>
struct identity
{
    using type = T;
};
(seit C++11)
8) Deduction-Guides von Member-Klassen-Templates:
struct S
{
    template<class CharT>
    struct NestedS
    {
        std::basic_string<CharT> s;
    };
    template<class CharT>
    NestedS(std::basic_string<CharT>) -> NestedS<CharT>;
};
(seit C++17)
9) Using-enum-Deklarationen :
enum class color { red, orange, yellow };
struct highlight
{
    using enum color;
};
(seit C++20)

Lokale Klassen

Eine Klassendeklaration kann im Rumpf einer Funktion erscheinen, in welchem Fall sie eine lokale Klasse definiert. Der Name einer solchen Klasse existiert nur innerhalb des Funktionsbereichs und ist von außen nicht zugänglich.

  • Mitglieder einer lokalen Klasse können nur in der Definition dieser Klasse deklariert werden, außer dass Mitglieder, die geschachtelte Klassen sind, auch im nächstgelegenen einschließenden Blockgültigkeitsbereich dieser Klasse deklariert werden können.
  • Eine innerhalb einer lokalen Klasse geschachtelte Klasse ist ebenfalls eine lokale Klasse.
  • Eine lokale Klasse kann keine statischen Datenelemente haben.
  • Mitgliedsfunktionen einer lokalen Klasse haben keine Verknüpfung.
  • Mitgliedsfunktionen einer lokalen Klasse müssen vollständig innerhalb des Klassenkörpers definiert werden.
  • Lokale Klassen außer Closure-Typen (seit C++14) können keine Mitgliedstemplates haben.
  • Lokale Klassen können keine Friend-Templates haben.
  • Lokale Klassen können keine Friend-Funktionen innerhalb der Klassendefinition definieren.
  • Eine lokale Klasse innerhalb einer Funktion (einschließlich Mitgliedsfunktion) kann auf dieselben Namen zugreifen, auf die die einschließende Funktion zugreifen kann.
  • Lokale Klassen konnten nicht als Template-Argumente verwendet werden.
(bis C++11)

#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
    std::vector<int> v{1, 2, 3};
    struct Local
    {
        bool operator()(int n, int m)
        {
            return n > m;
        }
    };
    std::sort(v.begin(), v.end(), Local()); // since C++11
    for (int n : v)
        std::cout << n << ' ';
    std::cout << '\n';
}

Ausgabe:

3 2 1

Schlüsselwörter

class , struct , union

Fehlerberichte

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

DR Angewendet auf Verhalten wie veröffentlicht Korrektes Verhalten
CWG 1693 C++98 Member-Deklarationen konnten nicht leer sein Leere Deklaration erlaubt
CWG 1930 C++98 member-declarator-list konnte leer sein, wenn decl-specifier-seq
eine Speicherklassenspezifikation oder CV-Qualifizierung enthält
Die Liste darf nicht leer sein
CWG 2890 C++98 Es war unklar, wo die Member verschachtelter Klassen deklariert werden können Klarstellung vorgenommen

Siehe auch

C-Dokumentation für Struct-Deklaration