Ich möchte meinen Speicher unter den Bedingungen auffrischen, unter denen ein Compiler normalerweise automatisch einen Standardkonstruktor, einen Kopierkonstruktor und einen Zuweisungsoperator generiert.
Ich erinnere mich, dass es einige Regeln gab, erinnere mich aber nicht und kann auch online keine seriöse Ressource finden. Kann jemand helfen?
"Automatisch generiert" bedeutet im Folgenden "implizit als Standard deklariert, aber nicht als gelöscht definiert". Es gibt Situationen, in denen die speziellen Elementfunktionen deklariert, aber als gelöscht definiert sind.
Ich fand das Diagramm unten sehr nützlich.
C++ 17 N4659-Standardentwurf
In den Abschnitten "Implizit deklariert" der folgenden cppreference-Einträge finden Sie eine kurze Querverweisliste:
Die gleichen Informationen können natürlich der Norm entnommen werden. Z.B. am C++ 17 N4659 Standardentwurf :
15.8.1 "Konstruktoren kopieren/verschieben" sagt für den Konstruktor kopieren:
6 Wenn die Klassendefinition einen Kopierkonstruktor nicht explizit deklariert, wird ein nicht expliziter Konstruktor implizit deklariert. Wenn die Klassendefinition einen Verschiebungskonstruktor oder einen Verschiebungszuweisungsoperator deklariert, wird der implizit deklarierte Kopierkonstruktor als gelöscht definiert. Andernfalls wird es als Standard definiert (11.4). Der letztere Fall ist veraltet, wenn die Klasse einen vom Benutzer deklarierten Kopierzuweisungsoperator oder einen vom Benutzer deklarierten Destruktor hat.
und für move Konstruktor:
8 Wenn die Definition einer Klasse X einen Verschiebungskonstruktor nicht explizit deklariert, wird ein nicht expliziter Konstruktor nur dann implizit als Standard deklariert, 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 Operator für die Zuweisung von Verschiebungen und
(8.4) - X hat keinen vom Benutzer deklarierten Destruktor.
15.8.2 "Kopier-/Verschiebungszuweisungsoperator" sagt für die Kopierzuweisung:
2 Wenn die Klassendefinition keinen expliziten Kopierzuweisungsoperator deklariert, wird einer implizit deklariert. Wenn die Klassendefinition einen Verschiebungskonstruktor oder einen Verschiebungszuweisungsoperator deklariert, wird der implizit deklarierte Kopierzuweisungsoperator als gelöscht definiert. Andernfalls wird es als Standard definiert (11.4). Letzterer Fall ist veraltet, wenn die Klasse über einen vom Benutzer deklarierten Kopierkonstruktor oder einen vom Benutzer deklarierten Destruktor verfügt.
und für die Zugzuteilung:
4 Wenn die Definition einer Klasse X keinen expliziten Verschiebungszuweisungsoperator deklariert, wird implizit nur dann einer als Standard deklariert, wenn
- (4.1) - X hat keinen vom Benutzer deklarierten Kopierkonstruktor,
- (4.2) - X hat keinen vom Benutzer deklarierten Verschiebungskonstruktor,
- (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 inline public Member seiner Klasse.