Bedingungen für die automatische Generierung von Default/Copy/Move-Ctor und Copy/Move-Zuweisungsoperator?

Lesezeit: 5 Minuten

Bedingungen fur die automatische Generierung von DefaultCopyMove Ctor und CopyMove Zuweisungsoperator
oompahloompah

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?

Bedingungen fur die automatische Generierung von DefaultCopyMove Ctor und CopyMove Zuweisungsoperator
Philipp

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).

  • Zählt ein geerbter Destruktor? Ich meine, sagen wir, ich habe eine Basisklasse mit einem leeren virtuellen Destruktor. Verhindert es die Erstellung von Bewegungskonstruktoren in Unterklassen? Wenn die Antwort ja ist, hilft es, wenn ich einen Bewegungskonstruktor in der Basisklasse definiere?

    – Kammilch

    6. Juli 2014 um 13:29 Uhr


  • Ich denke, dass Sie vielleicht das Haben erwähnen sollten const Mitglieder in der Klasse verhindern, dass der Konstruktor automatisch generiert wird …

    – Unsinn

    31. Juli 2014 um 23:08 Uhr

  • Tut “Es gibt Situationen, in denen die speziellen Elementfunktionen deklariert, aber als gelöscht definiert sind.” beziehen Sie sich darauf, wo Sie zum Beispiel Konstanten oder Verweiselemente haben, bei denen eine Bewegung unmöglich ist? Nein, das kann nicht sein, denn dort wird kopiert.

    – towi

    27. September 2016 um 7:37 Uhr


  • Ich weiß, dass das Senden von Hyperlinks in diesem Forum eingeschränkt ist. Aber es ist auch ein guter Artikel – cplusplus.com/articles/y8hv0pDG

    – Konstantin Burlachenko

    12. Oktober 2016 um 0:54 Uhr

  • Beachten Sie, dass standardmäßig ein implizit voreingestellter Kopierkonstruktor “ist veraltet, wenn die Klasse über einen vom Benutzer deklarierten Kopierzuweisungsoperator oder einen vom Benutzer deklarierten Destruktor verfügt” (12.8 Kopieren und Verschieben von Klassenobjekten [class.copy]).

    – sig

    29. März 2017 um 10:59 Uhr


1647148210 766 Bedingungen fur die automatische Generierung von DefaultCopyMove Ctor und CopyMove Zuweisungsoperator
Marco M.

Ich fand das Diagramm unten sehr nützlich.

C++-Regeln für automatische Konstruktoren und Zuweisungsoperatoren

von Sticky Bits – Werden Sie ein Rule of Zero-Held

  • Wunderschönen. Worauf bezieht sich „unabhängig“? Unabhängig von was?

    – towi

    27. September 2016 um 7:29 Uhr

  • Copy Ctor/Auftrag sind ‘unabhängig’ voneinander. Wenn Sie nur eine schreiben, stellt der Compiler die andere bereit. Wenn Sie dagegen entweder einen Bewegungsctor oder eine Bewegungszuweisung angeben, liefert der Compiler die andere nicht.

    – Marco M.

    3. Oktober 2016 um 20:14 Uhr

  • Frage mich, was der Grund dafür ist, dass Kopiervorgänge unabhängig sind. Historische Gründe mögen sein? oder die Tatsache, dass die Kopie ihr Ziel nicht ändert, aber die Bewegung?

    – RaGa__M

    5. Juli 2017 um 7:47 Uhr


  • @Explorer_N Ja, Abwärtskompatibilität, also historische Gründe. Vor langer Zeit war dies eine schlechte Designentscheidung, daher sind jetzt bewährte Verfahren wie die „Dreierregel“ (alle 3 oder keine definieren: Kopierkonstruktor, Kopierzuweisungsoperator und häufig Destruktor) erforderlich, um schwer zu findende Fehler zu vermeiden.

    – atablash

    31. März 2018 um 18:41 Uhr

  • @MarcoM. Soweit ich verstanden habe, umfasst die Bedingung “Wenn Sie schreiben …” die beiden Fälle, in denen die spezielle Elementfunktion festgelegt wird = delete (offensichtlich) bzw = default (für mich weniger offensichtlich). Habe ich recht?

    – Enliko

    19. Mai 2019 um 12:46 Uhr

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.

996040cookie-checkBedingungen für die automatische Generierung von Default/Copy/Move-Ctor und Copy/Move-Zuweisungsoperator?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy