Der implizit definierte Zuweisungsoperator in C++
Es ist möglich, einem Exemplar unserer Klasse einen Wert zuzuweisen, den wir von einem anderen Objekt derselben Klasse kopieren.
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
struct entity { ::std::string string; };
int main()
{ ::entity entity {};
::entity const other { "abc" };::std::cout << ']' << entity.string << "[\n"s;
entity = other; /* <- Zuweisung (Kopieren) */
::std::cout << ']' << entity.string << "[\n"s; }
transcript
][
]abc[
Dafür benötigt unsere Klasse einen Zuweisungsoperator.
Wir haben für unsere Klasse keine ausdrückliche (explizite) Definition eines Zuweisungsoperators angegeben.
Wird für eine Klasse kein Zuweisungsoperator vom Benutzer gestellt, so wird stillschweigend (implizit) ein Zuweisungsoperator zur Klasse hinzugefügt.
(Dieses Hinzufügen wird unterdrückt, falls ausdrücklich ein Kopierkonstruktor definiert wurde, aber nicht bei einer Definition eines Fehlkonstruktors.)
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
struct entity
{ ::std::string string;
entity( entity & e ): string{} {}};int main()
{ ::entity entity {};
::entity const other { "abc" };::std::cout << ']' << entity.string << "[\n"s;
entity = other; /* <- Zuweisung (Kopieren) */
::std::cout << ']' << entity.string << "[\n"s; }
- Protokoll
main.cpp: In function 'int main()':
main.cpp:12:20: error: no matching function for call to 'entity::entity(<brace-enclosed initializer list>)'
{ ::entity entity {};
^
main.cpp:9:3: note: candidate: entity::entity(entity&)
entity( entity & e ): string{} {}};
^
main.cpp:9:3: note: candidate expects 1 argument, 0 provided
main.cpp:13:32: error: no matching function for call to 'entity::entity(<brace-enclosed initializer list>)'
::entity const other { "abc" };
^
main.cpp:9:3: note: candidate: entity::entity(entity&)
entity( entity & e ): string{} {}};
^
main.cpp:9:3: note: no known conversion for argument 1 from 'const char [4]' to 'entity&'transcript
][
]abc[- Die Proklamationen der implizit definierten Elemente
entity();
entity( const entity & x );
entity & operator =( const entity & x );
Dieser implizit definierte Zuweisungsoperator ermöglicht es uns, im obigen Programm eine Zuweisung durchführen zu können, obwohl wir gar keinen Zuweisungsoperator definiert haben.
Zitate
- Die einzelnen Felder werden jeweils einzeln kopiert
- “The implicitly-defined copy/move constructor for a non-union class X performs a memberwise copy/move of its bases and members. ”, 2015 15.8.1p14
Vorgaben
Die Antwort auf die Frage Frage, ob ein spezielles Element vorgegeben wird, kann der folgenden Tabelle entnommen werden.
Falls mehrere Bedingungen der linkestens Spalte zutreffen, so ergeben Kombinationen von »vorgegeben« und »nicht-deklariert« »nicht-deklariert«.
»veraltend« bedeutet, daß in späteren Versionen der Norm »vorgegeben« möglicherweise durch »nicht-deklariert« zu ersetzen sein wird.
- Tabelle
.- Benutzer Fehl- Kopier- Zuweisung
| deklariert: konstruktor konstruktor
|
|
|
| nichts vorgegeben vorgegeben vorgegeben
|
| Fehl- benutzer- vorgegeben vorgegeben
| konstruktor deklariert
|
| Kopier- nicht benutzer- vorgegeben*
| konstruktor deklariert deklariert
|
| anderen nicht vorgegeben vorgegeben
| Konstruktor deklariert
|
| Zuweisung vorgegeben vorgegeben* benutzer-
| deklariert
'-
* = veraltend