Ich möchte meine Erinnerung an die Bedingungen auffrischen, unter denen ein Compiler normalerweise automatisch einen Standardkonstruktor, einen Kopierkonstruktor und einen Zuweisungsoperator generiert.
Ich erinnere mich, dass es einige Regeln gab, aber ich erinnere mich nicht und kann auch keine seriöse Ressource online finden. Kann jemand helfen?
Im Folgenden bedeutet „automatisch generiert“ „implizit als default deklariert, aber nicht als gelöscht definiert“. Es gibt Situationen, in denen die speziellen Elementfunktionen deklariert, aber als gelöscht definiert sind.
- Der Standardkonstruktor wird automatisch generiert, wenn es keinen vom Benutzer deklarierten Konstruktor gibt (§12.1/5).
- Der Kopierkonstruktor wird automatisch generiert, wenn es keinen vom Benutzer deklarierten Bewegungskonstruktor oder Bewegungszuweisungsoperator gibt (da es in C++03 keine Bewegungskonstruktoren oder Bewegungszuweisungsoperatoren gibt, vereinfacht sich dies zu „immer“ in C++03) ( §12.8/8).
- Der Kopierzuweisungsoperator wird automatisch generiert, wenn es keinen vom Benutzer deklarierten Bewegungskonstruktor oder Bewegungszuweisungsoperator gibt (§12.8/19).
- Der Destruktor wird automatisch generiert, wenn es keinen vom Benutzer deklarierten Destruktor gibt (§12.4/4).
Nur C++11 und höher:
- Der Bewegungskonstruktor wird automatisch generiert, wenn es keinen vom Benutzer deklarierten Kopierkonstruktor, Kopierzuweisungsoperator oder Destruktor gibt und wenn der generierte Bewegungskonstruktor gültig ist (§12.8/10).
- Der Verschiebungszuweisungsoperator wird automatisch generiert, wenn es keinen vom Benutzer deklarierten Kopierkonstruktor, Kopierzuweisungsoperator oder Destruktor gibt und wenn der generierte Verschiebungszuweisungsoperator gültig ist (z. B. wenn er keine konstanten Elemente zuweisen müsste) (§12.8/ 21).
Ich fand das Diagramm unten sehr nützlich.

von Sticky Bits – Werden Sie ein Rule of Zero-Held
C++17 N4659-Standardentwurf
Für eine schnelle Cross-Standard-Referenz werfen Sie einen Blick auf die „Implicitly-declared“-Abschnitte der folgenden cpreference-Einträge:
Dieselben Informationen können natürlich auch der Norm entnommen werden. Bsp an C++17 N4659-Standardentwurf:
15.8.1 „Konstruktoren kopieren/verschieben“ sagt für für Kopierkonstruktor:
6 Wenn die Klassendefinition keinen Kopierkonstruktor explizit deklariert, wird implizit ein nicht expliziter Konstruktor deklariert. Wenn die Klassendefinition einen Bewegungskonstruktor oder einen Bewegungszuweisungsoperator deklariert, wird der implizit deklarierte Kopierkonstruktor als gelöscht definiert; andernfalls wird es als ausgefallen definiert (11.4). Der letztere Fall ist veraltet, wenn die Klasse über einen vom Benutzer deklarierten Kopierzuweisungsoperator oder einen vom Benutzer deklarierten Destruktor verfügt.
und für den Bewegungskonstruktor:
8 Wenn die Definition einer Klasse X keinen Move-Konstruktor explizit deklariert, wird ein nicht expliziter implizit als default deklariert, wenn und nur wenn
-
(8.1) — X hat keinen vom Benutzer deklarierten Kopierkonstruktor,
-
(8.2) — X hat keinen vom Benutzer deklarierten Kopierzuweisungsoperator,
-
(8.3) — X hat keinen vom Benutzer deklarierten Zugzuweisungsoperator, und
-
(8.4) — X hat keinen vom Benutzer deklarierten Destruktor.
15.8.2 „Operator für Kopier-/Verschiebezuweisung“ sagt für die Kopierzuweisung:
2 Wenn die Klassendefinition keinen Kopierzuweisungsoperator explizit deklariert, wird implizit einer deklariert. Wenn die Klassendefinition einen Verschiebekonstruktor oder einen Verschiebezuweisungsoperator deklariert, wird der implizit deklarierte Kopierzuweisungsoperator als gelöscht definiert; andernfalls wird es als ausgefallen definiert (11.4). Der letztere Fall ist veraltet, wenn die Klasse über einen vom Benutzer deklarierten Kopierkonstruktor oder einen vom Benutzer deklarierten Destruktor verfügt.
und für die Zugzuweisung:
4 Wenn die Definition einer Klasse X keinen Move-Zuweisungsoperator explizit deklariert, wird einer implizit als default deklariert, wenn und nur wenn
- (4.1) — X hat keinen vom Benutzer deklarierten Kopierkonstruktor,
- (4.2) — X hat keinen vom Benutzer deklarierten Bewegungskonstruktor,
- (4.3) — X hat keinen vom Benutzer deklarierten Kopierzuweisungsoperator, und
- (4.4) — X hat keinen vom Benutzer deklarierten Destruktor.
15.4 “Destruktoren” sagt es für Destruktoren:
4 Wenn eine Klasse keinen vom Benutzer deklarierten Destruktor hat, wird ein Destruktor implizit als Standard deklariert (11.4). Ein implizit deklarierter Destruktor ist ein öffentliches Inline-Member seiner Klasse.