Namensräume
Varianten
Aktionen

Klassen

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
 
 

Eine Klasse ist ein benutzerdefinierter Typ.

Ein Klassentyp wird durch einen Klassenspezifizierer definiert, der in der decl-specifier-seq der Deklarationssyntax erscheint. Siehe Klassendeklaration für die Syntax des Klassenspezifizierers.

Eine Klasse kann die folgenden Arten von Membern haben:

1) Datenmember
2) Memberfunktionen
3) Verschachtelte Typen
a) Verschachtelte Klassen und Aufzählungen, die innerhalb der Klassendefinition definiert sind
b) Aliase für vorhandene Typen, definiert mit typedef oder Typalias (seit C++11)-Deklarationen
c) Der Name der Klasse innerhalb ihrer eigenen Definition fungiert für die Auflösung als öffentlicher Typalias für sich selbst (außer wenn er verwendet wird, um einen Konstruktor zu benennen): Dies ist bekannt als injected-class-name
4) Aufzählungen aus allen nicht-gesteckten Aufzählungen, die innerhalb der Klasse definiert sind, oder eingeführt durch using-Deklarationen oder using-enum-Deklarationen(seit C++20)
5) Member-Templates ( Variablentemplates, (seit C++14)Klassentemplates oder Funktionstemplates) können im Körper jeder nicht-lokalen Klasse/Struktur/Union erscheinen.

Alle Member werden gleichzeitig in der Klassendefinition definiert, sie können einer bereits definierten Klasse nicht hinzugefügt werden (im Gegensatz zu den Membern von Namespaces).

Ein Member einer Klasse T kann T nicht als seinen Namen verwenden, wenn der Member

  • ein statischer Datenmember ist,
  • eine Memberfunktion ist,
  • ein Membertyp ist,
  • ein Member-Template ist,
  • ein Aufzählungsbestandteil einer Aufzählung ist (es sei denn, die Aufzählung ist geschachtelt)(seit C++11), oder
  • ein Member einer anonymen Member-Union ist.

Ein nicht-statischer Datenmember darf jedoch den Namen T verwenden, solange keine benutzerdefinierten Konstruktoren vorhanden sind.

Eine Klasse mit mindestens einer deklarierten oder geerbten virtuellen Memberfunktion ist *polymorph*. Objekte dieses Typs sind *polymorphe Objekte* und haben zur Laufzeit Typinformationen, die als Teil der Objektbeschreibung gespeichert sind und mit dynamic_cast und typeid abgefragt werden können. Virtuelle Memberfunktionen nehmen an der dynamischen Bindung teil.

Eine Klasse mit mindestens einer deklarierten oder geerbten rein virtuellen Memberfunktion ist eine abstrakte Klasse. Objekte dieses Typs können nicht erstellt werden.

Eine Klasse mit einem constexpr-Konstruktor ist ein LiteralType: Objekte dieses Typs können zur Kompilierzeit von constexpr-Funktionen manipuliert werden.

(seit C++11)

Inhalt

[bearbeiten] Eigenschaften von Klassen

Trivially Copyable Class

Eine *trivially copyable class* ist eine Klasse, die

Triviale Klasse

Eine *triviale Klasse* ist eine Klasse, die

  • trivially copyable ist, und
  • einen oder mehrere berechtigte Standardkonstruktoren hat, von denen jeder *trivial* ist.
(veraltet in C++26)

Standard-Layout-Klasse

Eine *Standard-Layout-Klasse* ist eine Klasse, die

  • keine nicht-statischen Datenmember vom Typ einer nicht-Standard-Layout-Klasse (oder eines Arrays solcher Typen) oder Referenz hat,
  • keine virtuellen Funktionen und keine virtuellen Basisklassen hat,
  • die gleiche Zugriffskontrolle für alle nicht-statischen Datenmember hat,
  • keine nicht-Standard-Layout-Basisklassen hat,
  • nur eine Klasse in der Hierarchie nicht-statische Datenmember hat, und
  • informell gesprochen: keine der Basisklassen den gleichen Typ wie der erste nicht-statische Datenmember hat. Oder formal: gegeben die Klasse als S, keine Elemente der Menge M(S) von Typen als Basisklasse hat, wobei M(X) für einen Typ X definiert ist als
  • Wenn X ein nicht-union-Klassentyp ohne (möglicherweise geerbte) nicht-statische Datenmember ist, ist die Menge M(X) leer.
  • Wenn X ein nicht-union-Klassentyp ist, dessen erster nicht-statischer Datenmember vom Typ X0 ist (wobei dieses Element eine anonyme Union sein kann), besteht die Menge M(X) aus X0 und den Elementen von M(X0).
  • Wenn X ein Union-Typ ist, ist die Menge M(X) die Vereinigung aller M(Ui) und der Menge, die alle Ui enthält, wobei jedes Ui der Typ des i-ten nicht-statischen Datenmembers von X ist.
  • Wenn X ein Array-Typ mit Elementtyp Xe ist, besteht die Menge M(X) aus Xe und den Elementen von M(Xe).
  • Wenn X ein Nicht-Klassen-, Nicht-Array-Typ ist, ist die Menge M(X) leer.

Ein *Standard-Layout-Struct* ist eine Standard-Layout-Klasse, die mit dem Schlüsselwort struct oder dem Schlüsselwort class definiert wurde. Ein *Standard-Layout-Union* ist eine Standard-Layout-Klasse, die mit dem Schlüsselwort union definiert wurde.

(seit C++11)

[bearbeiten] Implizit-Lebenszeit-Klasse

Eine *implizit-lebenszeit-Klasse* ist eine Klasse, die

  • eine aggregierte Klasse ist, deren Destruktor nicht benutzerdefiniert(bis C++11)benutzerbereitgestellt(seit C++11) ist, oder
  • mindestens einen trivialen berechtigten Konstruktor und einen trivialen, nicht gelöschten Destruktor hat.

Hinweise: Die Eigenschaft "implizit-lebenszeit" wird durch den Fehlerbericht P0593R6 klargestellt.

[bearbeiten] POD-Klasse

Eine *POD-Klasse* ist eine Klasse, die

  • eine aggregierte Klasse ist,
  • keinen benutzerdefinierten Kopierzuweisungsoperator hat,
  • keinen benutzerdefinierten Destruktor hat, und
  • keine nicht-statischen Datenmember vom Typ einer nicht-POD-Klasse (oder eines Arrays solcher Typen) oder Referenz hat.
(bis C++11)
  • eine triviale Klasse ist,
  • eine Standard-Layout-Klasse ist, und
  • keine nicht-statischen Datenmember vom Typ einer nicht-POD-Klasse (oder eines Arrays solcher Typen) hat.
(seit C++11)

Ein *POD-Struct* ist eine Nicht-Union-POD-Klasse. Ein *POD-Union* ist ein Union, das eine POD-Klasse ist.

(veraltet in C++20)

[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 148 C++98 POD-Klassen konnten keine Zeiger auf Member enthalten,
die selbst POD- (skalare) Typen sind.
Beschränkung aufgehoben
CWG 383 C++98 Kopierzuweisungsoperatoren oder Destruktoren konnten
in POD-Klassen benutzerdefiniert sein, wenn sie nicht definiert waren.
nicht erlaubt
CWG 1363 C++11 Eine Klasse, die gleichzeitig triviale Standardkonstruktoren und nicht-triviale
Standardkonstruktoren hat, könnte trivial sein.
sie ist nicht-trivial
CWG 1496 C++11 Eine Klasse, die nur Konstruktoren hat, die
alle als gelöscht definiert sind, könnte trivial sein.
sie ist nicht-trivial
CWG 1672 C++11 Eine Klasse konnte eine Standard-Layout-Klasse sein,
wenn sie mehrere leere Basisklassen hat.
sie ist keine Standard-Layout-Klasse
CWG 1734 C++11 Eine trivial kopierbare Klasse konnte keine nicht-trivialen
gelöschten Kopier-/Verschiebungskonstruktoren/Zuweisungsoperatoren haben.
kann trivial sein, wenn gelöscht
CWG 1813 C++11 Eine Klasse war nie eine Standard-Layout-Klasse, wenn sie eine
Basisklasse hat, die einen nicht-statischen Datenmember erbt.
sie kann eine Standard-Layout-Klasse sein
CWG 1881 C++11 Für eine Standard-Layout-Klasse und ihre Basisklassen
konnten unbenannte Bitfelder in einer
anderen Klasse deklariert werden, die die Datenmember deklariert.
alle nicht-statischen Datenmember
und Bitfelder müssen zuerst
in derselben Klasse deklariert werden.
CWG 1909 C++98 Ein Member-Template konnte denselben Namen wie seine Klasse haben. verboten
CWG 2120 C++11 Die Definition von M(X) bei der Bestimmung einer Standard-
Layout-Klasse berücksichtigte nicht den Fall
einer Klasse, deren erstes Element ein Array ist.
adressiert diesen Fall in
der Definition von M(X).
CWG 2605 C++98 Eine implizit-lebenszeit-Klasse konnte einen benutzergestellten Destruktor haben. verboten