Kleine Taxonomie für Typen (fundamental, POD, UDT, ...)
-
Da es hierzu öfter Fragen gibt (was ist ein POD? was ist ein UDT? etc.) habe ich mal eine kleine Übersicht gemacht, die vielleicht als nützlich angesehen wird.
Kritik und Ergänzungsvorschläge sind willkommen.- bedeutet, dass genau ein Punkt der Aufzählung ist für den jeweiligen Typ zutreffend ist
x bedeutet, dass alle Punkte der Aufzählung für den jeweiligen Typen zutreffenAlle Typen
- Fundamentale Typen (fundamental types)
- arithmetische Typen (arithmetic types)
- integrale Typen (integral types)
- vorzeichenbehaftete integrale Typen (signed integral types)
- signed char
- short
- int
- long
- (long long)- vorzeichenlose integrale Typen (unsigned integral types)
- unsigned char
- unsigned short
- unsigned
- unsigned long
- (unsigned long long)- andere
- char: verhält sich implementationsabhängig entweder wie signed char oder unsigned char
- wchar_t: verhält sich implementationsabhängig wie ein bestimmter vorzeichenloser oder vorzeichenbehafteter integraler Typ
- bool: ist vorzeichenlos, gehört aber nicht zu dieser Kategorie und braucht ein paar Sonderregeln- Gleitkommatypen (floating point types)
- float
- double
- long double- void
- Zusammengesetzte Typen (compound types)
- Arrays (arrays)
- Funktionen (functions)
- Zeiger auf Objekte oder Funktionen oder void (pointer)
- Referenzen auf Objekte oder Funktionen (references)
- Klassen (classes)- union
- Strukturen (structs)- struct
- class- Aufzählungen (enumerations)
- Zeiger auf nicht-statische Member (pointer to (non-static) member): das "nicht-statisch" lässt man für gewöhnlich wegObjekttypen (object types)
- alle außer void, Referenzen, Funktionen
Skalare Typen (scalar types): alle Objekttypen, die keine Komponenten haben
- arithmetische Typen
- Zeiger
- Zeiger auf Member
- AufzählungenAggregate (aggregates)
- Arrays
- Klassenx ohne vom Nutzer deklarierte Konstruktoren
x ohne nicht-statische protected oder private Datenmember
x ohne Basisklassen
x ohne virtuelle FunktionenPOD (plain old data) - rekursive Definition:
- Skalare Typen
- POD-Klassex Klassen-Aggregat
x ohne vom Nutzer deklarierten Destruktor
x ohne vom Nutzer deklarierten Zuweisungsoperator
x ohne nichtstatische nicht-POD-Datenmember- union: POD-union
- Struktur: POD-struct- Arrays aus PODs
PODs sind layoutkompatibel zu ihrem Äquivalent in C (sofern es eins gibt). Ihre Lebenszeit entspricht der Dauer der Reservierung von Speicher für diesen Typ,
der Ausführung eines Konstruktors oder Destruktors bedarf es nicht. zudem dürfen sie mit Funktionen wie etwa memcpy modifiziert werden.UDT (user defined types)
- Klassen
- Aufzählungen"eingebaute Typen" (build-in types): informell
- Typen, die keine UDTs sind
Jeder Typ außer Referenzen kann als Typ eines Ausdrucks auftreten.
Typen können vollständig oder unvollständig sein.
Ein Typ ist unvollständig, wenn es sich um void oder um eine Klasse handelt, die deklariert und noch nicht definiert wurde.
Zudem sind Arraytypen unvollständig, solange ihr Elementtyp unvollständig ist, oder ihre Dimension unspezifiziert ist.
Sonst ist der Typ vollständig.
Ein unvollständiger Typ genügt in der Regel in einer Deklaration, die keine Definition ist. Wichtigste Ausnahme davon ist die Deklaration von
nicht-statischen Datenmembern.Alle Typen außer Referenzen, Funktionen und Arrays können mit const oder volatile qualifiziert sein. Das ändert nicht ihre Klassifikation in obigem Schema, aber sie
sind verschieden von dem entsprechenden Typ mit anderer cv-Qualifikation. Ein cv-qualifizierter Typ ist vollständig, wenn die
unqualifizierte Version vollständig ist.
-
camper hat in einem anderen Thread die Auflistung für die neuen Begriffe und Änderungen in C++11 aktualisiert:
camper schrieb:
- bedeutet, dass genau ein Punkt der Aufzählung ist für den jeweiligen Typ zutreffend ist x bedeutet, dass alle Punkte der Aufzählung für den jeweiligen Typen zutreffen Alle Typen - Fundamentale Typen (fundamental types 3.9.1) - arithmetische Typen (arithmetic types 3.9.1/8) - integrale Typen (integral types / integer types 3.9.1/7) - vorzeichenbehaftete integrale Typen (signed integer types 3.9.1/2) - vorzeichenbehaftet integrale Standardtypen (standard signed integer types 3.9.1/2) - signed char - short - int - long - long long - erweiterte vorzeichenbehaftete Integer (extended signed integer types 3.9.1/2) - optional (implementation-defined) - vorzeichenlose integrale Typen (unsigned integral types 3.9.1/3) - vorzeichenlose integrale Standardtypen (standard unsigned integer types 3.9.1/3) - unsigned char - unsigned short - unsigned - unsigned long - unsigned long long - erweiterte vorzeichenbehaftete Integer (extended unsigned integer types 3.9.1/3) - optional (implementation-defined) - andere - bool: ist vorzeichenlos, gehört aber nicht zu dieser Kategorie und braucht ein paar Sonderregeln (3.9.1/6) - char: verhält sich implementationsabhängig entweder wie signed char oder unsigned char (3.9.1/1) - wchar_t: verhält sich implementationsabhängig wie ein bestimmter vorzeichenloser oder vorzeichenbehafteter integraler Typ (3.9.1/5) - char16_t: eigenständiger Typ, äquivalent zu std::uint_least16_t (3.9.1/5) - char32_t: eigenständiger Typ, äquivalent zu std::uint_least32_t (3.9.1/5) - Gleitkommatypen (floating point types 3.9.1/8) - float - double - long double - void (3.9.1/9) - std::nullptr_t (3.9.1/10) - Zusammengesetzte Typen (compound types 3.9.2) - Arrays (arrays) - Funktionen (functions) - Zeiger (pointer) - Objektzeiger (object pointer types 3.9.2/3) - Zeiger auf Objekte (pointer to object types) - Zeiger auf void (pointer to void) - Funktionszeiger (function pointer types 3.9.2/3) - Referenzen auf Objekte oder Funktionen (references) - lvalue-Referenzen (lvalue references) - rvalue-Referenzen (rvalue references) - Klassen (classes) - union - Strukturen (structs) - struct - class - Aufzählungen (enumerations) (s.u.) - Zeiger auf nicht-statische Member (pointer to (non-static) member) Zeichentypen (character types) - char - signed char - unsigned char Objekttypen (object types 3.9/8) - alle außer void, Referenzen, Funktionen Skalare Typen (scalar types): alle Objekttypen, die keine Komponenten haben - arithmetische Typen - Zeiger - Zeiger auf Member - Aufzählungen - std::nullptr_t Aufzählungen - unscoped enumerations ([i]enum-key[/i] = enum) - Aufzählungskonstanten werden im gleichen Scope wie die Aufzählung selbst plaziert - scoped enumerations ([i]enum-key[/i] = enum class / enum struct) - Aufzählung bildet einen eigenen Scope, in dem sich die Aufzählungskonstanten befinden, keine implizite Konvertierung in integer Aufzählungstypen haben einen zugrundeliegenden integralen Typen (underlying type), der für die Repräsentation verwendet werden kann. Dieser kann explizit angegeben werden (enum-base), wird er nicht angegeben, so ist er int im Falle von scoped Aufzählungen. In diesen Fällen ist der zugrundeliegende Typ fest (fixed). Im Falle von unscoped Aufzählungen ohne Angabe ist der Typ unspezifiziert mit bestimmten Einschränkungen (Details in 7.2/6), in der Praxis typischerweise int oder - soweit erforderlich - ein größerer Typ. Aggregate (aggregates) - Arrays - Klassen x ohne vom Nutzer deklarierte Konstruktoren x ohne nicht-statische protected oder private Datenmember x ohne Basisklassen x ohne virtuelle Funktionen x ohne Initialisierer für nichtstatische Member POD (plain old data) - rekursive Definition: - Skalare Typen - POD-Klasse x Klassen-Aggregat x ohne vom Nutzer deklarierten Destruktor x ohne vom Nutzer deklarierten Zuweisungsoperator x ohne nichtstatische nicht-POD-Datenmember - union: POD-union - Struktur: POD-struct - Arrays aus PODs Alle POD-Typen sind trivial und haben Standard-Layout. Literaltypen (literal types) - Skalare Typen - Referenzen auf Literaltypen - Array aus Literalen - Klassen x trivialer Destruktor x alle Initialisierer für nichtstatische Member (sofern vorhanden) sind konstante Ausdrücke x Entweder - Aggregat - mindestens eine constexpr-Konstruktor, der kein Copy- oder Movekonstruktor ist x alle nichtstatischen Datenmember und Basisklassen sind Literaltypen Trivial kopierbare Typen (trivially copyable types 3.9/9) - Skalare Typen - Trivial kopierbare Klassen x kein nicht-trivialer Copy-Konstruktor* x kein nicht-trivialer Move-Konstruktor* x kein nicht-trivialer Copy-Zuweisungsoperator* x kein nicht-trivialer Move-Zuweisungsoperator* x trivialer Destruktor* - Arrays solcher Typen Triviale Typen (trivial types 3.9/9) - Skalare Typen - Triviale Klassen x trivial kopierbare Klasse x trivialer Defaultkonstruktor - Arrays solcher Typen Alle trivialen Typen sind trivial kopierbar. Standardlayout-Typen (standard-layout types) - Skalare Typen - Standardlayout Klassen x nichtstatische Daten-Member haben Standardlayout x Basisklassen haben Standardlayout x keine virtuellen Funktionen x keine virtuellen Basisklassen x gleiche Zugriffskontrolle für alle nichstatischen Datenmember x höchtens 1 Klasse in der gesamten Vererbungshierarchie definiert nichtstatische Daten-Member x 1. Daten-Member (wenn vorhanden) ist nicht gleichzeitig Basisklasse - Arrays solcher Typen UDT (user defined types) - Klassen - Aufzählungen "eingebaute Typen" (build-in types): informell - Typen, die keine UDTs sind triviale Memberfunktionen ------------------------- Eine spezielle Memberfunktion ist user-provided, wenn sie explizit deklariert wird, und diese 1. Deklaration weder explizit defaulted noch explizit deleted ist. Zur Vereinfachung im Folgenden: Eine Subobjektklasse sei eine Klasse, bei der es sich entweder um eine (direkte) Basisklasse oder den Klassentyp eines nichtstatischen Members, oder den Klassentype eines Elementes eines nichtstatischen Memberarrays handelt. Eine spezielle Memberfunktion ist trivial, wenn x sie nicht user-provided ist, x korrespondierende Memberfunktionen aller Subobjektklassen trivial sind, x im Falle des Defaultkonstruktors kein nichtstatischer Member über einen Initialisierer verfügt, x und - im Falle des Destruktors dieser nicht virtuell ist, sonst - die Klasse keine virtuellen Funktionen und keine virtuellen Basisklassen hat Korrespondierende Memberfunktionen i.o.S. sind - im Falle eines Defaultkonstruktors - die Defaultkonstruktoren der Subobjektklassen - im Falle des Destruktors - die Destruktoren der Subobjektklassen - sonst - die Memberfunktionen, die für Copy-/Move der Subobjekte ausgewählt werden (dabei handelt es sich nicht notwendigerweise um Copy-/Move-Konstruktoren oder Zuweisungsoperatoren, allerdings können nur solche trivial sein)