Default constructors
Ein Standardkonstruktor ist ein Konstruktor , der ohne Argumente aufgerufen werden kann.
Inhaltsverzeichnis |
Syntax
class-name
(
parameter-list
(optional)
);
|
(1) | ||||||||
class-name
(
parameter-list
(optional)
)
function-body
|
(2) | ||||||||
class-name
() = default;
|
(3) | (seit C++11) | |||||||
class-name
(
parameter-list
(optional)
) = delete;
|
(4) | (seit C++11) | |||||||
class-name
::
class-name
(
parameter-list
(optional)
)
function-body
|
(5) | ||||||||
class-name
::
class-name
() = default;
|
(6) | (seit C++11) | |||||||
| class-name | - | die Klasse, deren Standardkonstruktor deklariert wird |
| parameter-list | - | eine Parameterliste , in der alle Parameter (außer Parameter Packs ) (seit C++11) über Standardargumente verfügen |
| function-body | - | der Funktionsrumpf des Standardkonstruktors |
Erklärung
Default-Konstruktoren werden während Default-Initialisierung und Wertinitialisierung aufgerufen.
Implizit deklarierter Standardkonstruktor
Wenn kein benutzerdeklarierter Konstruktor oder Konstruktortemplate für einen Klassentyp vorhanden ist, wird der Compiler implizit einen Standardkonstruktor als inline public Mitglied seiner Klasse deklarieren.
Der implizit deklarierte (oder bei seiner ersten Deklaration defaulted) Standardkonstruktor hat eine Ausnahmespezifikation, wie beschrieben in dynamische Ausnahmespezifikation (bis C++17) noexcept-Spezifikation (seit C++17) .
Implizit definierter Standardkonstruktor
Wenn der Konstruktor implizit deklariert ist (bis C++11) der implizit deklarierte oder explizit defaulted Standardkonstruktor nicht als gelöscht definiert ist (seit C++11) , wird er implizit durch den Compiler definiert, wenn odr-used oder needed for constant evaluation oder wenn er explizit nach seiner ersten Deklaration defaulted wird (seit C++11) .
|
Wenn ein Standardkonstruktor einer
Union-ähnlichen Klasse
|
(seit C++26) |
Ein (bis C++26) Andernfalls hat ein (seit C++26) implizit definierter Standardkonstruktor denselben Effekt wie ein benutzerdefinierter Konstruktor mit leerem Rumpf und leerer Initialisierungsliste. Das heißt, er ruft die Standardkonstruktoren der Basisklassen und der nicht-statischen Member dieser Klasse auf. Klassentypen mit einem leeren benutzerbereitgestellten Konstruktor können während der Wertinitialisierung anders behandelt werden als solche mit einem implizit definierten Standardkonstruktor.
|
Wenn dies die Anforderungen eines constexpr Konstruktors (bis C++23) constexpr Funktion (seit C++23) erfüllt, ist der generierte Konstruktor constexpr . Falls benutzerdefinierte Konstruktoren vorhanden sind, kann der Benutzer die automatische Generierung eines Standardkonstruktors durch den Compiler, der sonst implizit deklariert worden wäre, mit dem Schlüsselwort default erzwingen. |
(seit C++11) |
Gelöschter Standardkonstruktor
Der implizit deklarierte oder explizit defaulted Standardkonstruktor für Klasse
Wenn keine benutzerdefinierten Konstruktoren vorhanden sind und der implizit deklarierte Standardkonstruktor nicht trivial ist, kann der Benutzer die automatische Generierung eines implizit definierten Standardkonstruktors durch den Compiler weiterhin mit dem Schlüsselwort delete unterbinden. |
(seit C++11) |
Trivialer Standardkonstruktor
Der Standardkonstruktor für die Klasse
T
ist trivial, wenn alle folgenden Bedingungen erfüllt sind:
- Der Konstruktor ist implizit deklariert (bis C++11) nicht benutzerbereitgestellt (seit C++11) .
-
That keine virtuellen Memberfunktionen. -
That keine virtuellen Basisklassen.
|
(since C++11) |
-
Jede direkte Basis von
That einen trivialen Standardkonstruktor.
|
(bis C++26) |
|
(seit C++26) |
Ein trivialer Standardkonstruktor ist ein Konstruktor, der keine Aktion ausführt. Alle mit der C-Sprache kompatiblen Datentypen (POD-Typen) sind trivial standardkonstruierbar.
Berechtigter Standardkonstruktor
|
Ein Standardkonstruktor ist berechtigt, wenn er entweder benutzerdeklariert oder sowohl implizit deklariert als auch definierbar ist. |
(until C++11) |
|
Ein Standardkonstruktor ist berechtigt, wenn er nicht gelöscht ist. |
(since C++11)
(until C++20) |
|
Ein Standardkonstruktor ist berechtigt, wenn alle folgenden Bedingungen erfüllt sind:
|
(since C++20) |
Die Trivialität von qualifizierten Standardkonstruktoren bestimmt, ob die Klasse ein implicit-lifetime type ist, und ob die Klasse ein trivially copyable type ist.
Hinweise
| Feature-Test-Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_trivial_union
|
202502L
|
(C++26) | Lockerung der Trivialitätsanforderungen für spezielle Memberfunktionen von Unions |
Beispiel
struct A { int x; A(int x = 1): x(x) {} // benutzerdefinierter Standardkonstruktor }; struct B : A { // B::B() ist implizit definiert, ruft A::A() auf }; struct C { A a; // C::C() ist implizit definiert, ruft A::A() auf }; struct D : A { D(int y) : A(y) {} // D::D() ist nicht deklariert, da ein anderer Konstruktor existiert }; struct E : A { E(int y) : A(y) {} E() = default; // explizit standardmäßig, ruft A::A() auf }; struct F { int& ref; // Referenzmitglied const int c; // konstantes Mitglied // F::F() ist implizit als gelöscht definiert }; // benutzerdeklarierter Kopierkonstruktor (entweder benutzerbereitgestellt, gelöscht oder standardmäßig) // verhindert die implizite Generierung eines Standardkonstruktors struct G { G(const G&) {} // G::G() ist implizit als gelöscht definiert }; struct H { H(const H&) = delete; // H::H() ist implizit als gelöscht definiert }; struct I { I(const I&) = default; // I::I() ist implizit als gelöscht definiert }; int main() { A a; B b; C c; // D d; // Kompilierungsfehler E e; // F f; // Kompilierungsfehler // G g; // Kompilierungsfehler // H h; // Kompilierungsfehler // I i; // Kompilierungsfehler }
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 1353 | C++11 |
die Bedingungen, unter denen implizit deklarierte Standardkonstruktoren
als gelöscht definiert sind, berücksichtigten keine mehrdimensionalen Array-Typen |
diese Typen berücksichtigen |
| CWG 2084 | C++11 |
Standard-Member-Initialisierer hatten keinen Einfluss darauf, ob
ein standardmäßiger Standardkonstruktor einer Union gelöscht ist |
sie verhindern, dass der standardmäßige Standard-
konstruktor gelöscht wird |
| CWG 2595 | C++20 |
ein Standardkonstruktor war nicht berechtigt, wenn es
einen anderen Standardkonstruktor gibt, der stärker eingeschränkt ist aber seine zugehörigen Constraints nicht erfüllt |
er kann in diesem Fall berechtigt sein |
| CWG 2871 | C++98 |
ein Standardkonstruktor würde implizit deklariert werden
selbst wenn ein benutzerdeklarierter Konstruktortemplate vorhanden ist |
keine implizite Deklaration
in diesem Fall |