Ich werde hier einige irrelevante Punkte auslassen, z.B. über union
s, Basisklassen, geschweifte oder gleich initialisierte usw. Wenn Ihre Klassen Mitglieder, Basisklassen, ... haben, dann wird die Antwort anders aussehen. Zum Beispiel, wenn Sie ein const
Mitglied haben, würde ein implizit deklarierter Zuweisungsoperator als gelöscht definiert werden.
Standardkonstruktor
[class.ctor]/5
Ein Standardkonstruktor für eine Klasse X
ist ein Konstruktor der Klasse X
, der ohne Argument aufgerufen werden kann. Wenn kein benutzerdeklarierter Konstruktor für die Klasse X
existiert, wird ein Konstruktor ohne Parameter implizit als standardmäßig deklariert. Ein implizit deklarierter Standardkonstruktor ist ein inline öffentliches
Element seiner Klasse. Ein standardmäßig deklarierter Standardkonstruktor für die Klasse X
wird als gelöscht definiert, wenn [... hier viele irrelevante Punkte folgen].
Also in den Fällen a) und e) [ohne benutzerdeklarierten Konstruktor], wird ein Standardkonstruktor als standardmäßig deklariert.
Standarddestruktor
[class.dtor]
4 Wenn eine Klasse keinen benutzerdeklarierten Destruktor hat, wird ein Destruktor implizit als standardmäßig deklariert. Ein implizit deklarierter Destruktor ist ein inline öffentliches
Element seiner Klasse.
5 Ein standardmäßig deklarierter Destruktor für eine Klasse X
wird als gelöscht definiert, wenn [... hier viele irrelevante Punkte folgen]
Also in allen Fällen außer a) [mit einem benutzerdeklarierten dtor] wird ein Standarddestruktor implizit deklariert und implizit definiert, wenn er odr-verwendet wird.
Wie in [class.copy]/2+3 dargelegt, können ein Kopierkonstruktor und ein Bewegungskonstruktor zusätzliche Parameter haben, wenn diese Standardwerte haben.
Kopierkonstruktor
Ein Kopierkonstruktor wird implizit deklariert, wenn kein benutzerdefinierter Kopierkonstruktor existiert (ein Konstruktorvorlage ist niemals ein Kopierkonstruktor). [class.copy]/7
Wenn die Klassendefinition einen Bewegungskonstruktor oder eine Bewegungszuweisungsoperator deklariert, wird der implizit deklarierte Kopierkonstruktor als gelöscht definiert; sonst wird er als standardmäßig definiert. Im letzteren Fall ist es veraltet, wenn die Klasse einen benutzerdeklarierten Kopierzusweisungsoperator oder einen benutzerdeklarierten Destruktor hat.
Das bedeutet, in allen Fällen außer d) [mit einem benutzerdeklarierten Kopierkonstruktor] wird ein Kopierkonstruktor implizit deklariert. In den Fällen b) und c) [mit einem benutzerdefinierten Bewegungskonstruktor] wird der Kopierkonstruktor als gelöscht definiert. Für a) [benutzerdeklarierter Destruktor] und e) [benutzerdeklarierter Kopierzuteilungsoperator] kann er als standardmäßig definiert sein, aber das ist veraltet.
Bewegungskonstruktor
Der Bewegungskonstruktor wird in diesen Fällen nicht einmal deklariert [class.copy]/9
X
hat keinen benutzerdeklarierten Kopierkonstruktor,
X
hat keinen benutzerdeklarierten Kopierzuteilungsoperator,
X
hat keinen benutzerdeklarierten Bewegungszuweisungsoperator,
X
hat keinen benutzerdeklarierten Destruktor, und
- der Bewegungskonstruktor würde nicht implizit als gelöscht definiert werden.
Es gibt wieder einige Fälle, in denen er als gelöscht definiert werden würde, aber diese treffen hier nicht zu.
Der Bewegungskonstruktor wird also nicht in einem der Fälle deklariert.
Kopierzuteilungsoperator
In [class.copy]/18:
Wenn die Klassendefinition nicht explizit einen Kopierzuteilungsoperator deklariert, wird er implizit deklariert. Wenn die Klassendefinition einen Bewegungskonstruktor oder einen Bewegungszuweisungsoperator deklariert, wird der implizit deklarierte Kopierzuteilungsoperator als gelöscht definiert; sonst wird er als standardmäßig definiert. Im letzteren Fall ist es veraltet, wenn die Klasse einen benutzerdeklarierten Kopierkonstruktor oder einen benutzerdeklarierten Destruktor hat.
Er wird in einigen Fällen als gelöscht definiert, siehe [class.copy]/23, aber diese treffen hier nicht zu.
Der Kopierzuteilungsoperator wird in allen Fällen außer e) [benutzerdeklarierter Kopierzuteilungsoperator] deklariert. Er wird in b) und c) [beide: benutzerdefinierter Bewegungskonstruktor] als gelöscht definiert; und er kann in a) [benutzerdeklarierter Destruktor] und d) [benutzerdeklarierter Kopierkonstruktor] als standardmäßig definiert sein. Beachten Sie die Parallele zum Kopierkonstruktor.
Bewegungszuweisungsoperator
Ähnlich wie beim Bewegungskonstruktor wird der Bewegungszuweisungsoperator nicht einmal deklariert, wenn entweder [class.copy]/20:
X
hat keinen benutzerdeklarierten Kopierkonstruktor,
X
hat keinen benutzerdeklarierten Bewegungskonstruktor,
X
hat keinen benutzerdeklarierten Kopierzuteilungsoperator,
X
hat keinen benutzerdeklarierten Destruktor, und
- der Bewegungszuweisungsoperator würde nicht implizit als gelöscht definiert werden.
Er wird in einigen Fällen als gelöscht definiert, siehe [class.copy]/23 (derselbe Absatz wie beim Kopierkonstruktor), aber diese treffen hier nicht zu.
Ein Bewegungszuweisungsoperator wird implizit deklariert und als standardmäßig definiert in keinem der Fälle.