Assignment operators
Zuweisungsoperatoren modifizieren den Wert des Objekts.
| Operatorname | Syntax | Überladbar | Prototypbeispiele (für class T ) | |
|---|---|---|---|---|
| Innerhalb der Klassendefinition | Außerhalb der Klassendefinition | |||
| Einfache Zuweisung |
a = b
|
Ja | T & T :: operator = ( const T2 & b ) ; | Nicht zutreffend |
| Zuweisungsaddition |
a += b
|
Ja | T & T :: operator + = ( const T2 & b ) ; | T & operator + = ( T & a, const T2 & b ) ; |
| Subtraktionszuweisung |
a -= b
|
Ja | T & T :: operator - = ( const T2 & b ) ; | T & operator - = ( T & a, const T2 & b ) ; |
| Multiplikationszuweisung |
a *= b
|
Ja | T & T :: operator * = ( const T2 & b ) ; | T & operator * = ( T & a, const T2 & b ) ; |
| Divisionszuweisung |
a /= b
|
Ja | T & T :: operator / = ( const T2 & b ) ; | T & operator / = ( T & a, const T2 & b ) ; |
| Rest-Zuweisung |
a %= b
|
Ja | T & T :: operator % = ( const T2 & b ) ; | T & operator % = ( T & a, const T2 & b ) ; |
| Bitweise UND-Zuweisung |
a &= b
|
Ja | T & T :: operator & = ( const T2 & b ) ; | T & operator & = ( T & a, const T2 & b ) ; |
| Bitweise-ODER-Zuweisung |
a |= b
|
Ja | T & T :: operator | = ( const T2 & b ) ; | T & operator | = ( T & a, const T2 & b ) ; |
| Bitweise XOR-Zuweisung |
a ^= b
|
Ja | T & T :: operator ^ = ( const T2 & b ) ; | T & operator ^ = ( T & a, const T2 & b ) ; |
| Bitweise Linksverschiebungszuweisung |
a <<= b
|
Ja | T & T :: operator <<= ( const T2 & b ) ; | T & operator <<= ( T & a, const T2 & b ) ; |
| Bitweise Rechtsverschiebungszuweisung |
a >>= b
|
Ja | T & T :: operator >>= ( const T2 & b ) ; | T & operator >>= ( T & a, const T2 & b ) ; |
|
||||
Inhaltsverzeichnis |
Definitionen
Copy assignment ersetzt die Inhalte des Objekts a mit einer Kopie der Inhalte von b ( b wird nicht modifiziert). Für Klassentypen wird dies in einer speziellen Memberfunktion durchgeführt, beschrieben im copy assignment operator .
|
Move-Zuweisung ersetzt die Inhalte des Objekts a mit den Inhalten von b und vermeidet dabei nach Möglichkeit das Kopieren ( b kann modifiziert werden). Für Klassentypen wird dies in einer speziellen Elementfunktion durchgeführt, beschrieben im Move-Zuweisungsoperator . |
(seit C++11) |
Für Nicht-Klassentypen sind Kopier- und Verschiebezuweisung nicht unterscheidbar und werden als direkte Zuweisung bezeichnet.
Zusammengesetzte Zuweisung ersetzt den Inhalt des Objekts a mit dem Ergebnis einer binären Operation zwischen dem vorherigen Wert von a und dem Wert von b .
Zuweisungsoperator-Syntax
Die Zuweisungsausdrücke haben die Form
target-expr
=
new-value
|
(1) | ||||||||
| target-expr op new-value | (2) | ||||||||
| target-expr | - | der Ausdruck [1] , dem zugewiesen werden soll |
| op | - | einer von * = , / = % = , + = - = , <<= , >>= , & = , ^ = , | = |
| new-value | - | die Expression [2] (bis C++11) Initialisierungsanweisung (seit C++11) , die dem Ziel zugewiesen wird |
- ↑ target-expr muss eine höhere Präzedenz als ein Zuweisungsausdruck haben.
- ↑ new-value kann kein Komma-Ausdruck sein, da dessen Präzedenz niedriger ist.
|
Wenn new-value kein Ausdruck ist, wird der Zuweisungsausdruck niemals einen überladenen zusammengesetzten Zuweisungsoperator entsprechen. |
(since C++11) |
Eingebauter einfacher Zuweisungsoperator
Für die eingebaute einfache Zuweisung muss target-expr ein modifizierbarer Lvalue sein.
Das Objekt, auf das durch
target-expr
verwiesen wird, wird modifiziert, indem sein Wert durch das Ergebnis von
new-value
ersetzt wird. Wenn das referenzierte Objekt einen Integer-Typ
T
hat und das Ergebnis von
new-value
vom entsprechenden vorzeichenbehafteten/vorzeichenlosen Integer-Typ ist, wird der Wert des Objekts durch den Wert vom Typ
T
mit derselben Wertdarstellung wie das Ergebnis von
new-value
ersetzt.
Das Ergebnis einer eingebauten einfachen Zuweisung ist ein Lvalue des Typs von target-expr , der sich auf target-expr bezieht. Wenn target-expr ein Bitfeld ist, ist das Ergebnis ebenfalls ein Bitfeld.
Zuweisung aus einem Ausdruck
Wenn new-value ein Ausdruck ist, wird er implizit konvertiert in den cv-unqualifizierten Typ von target-expr . Wenn target-expr ein Bitfeld ist, das den Wert des Ausdrucks nicht darstellen kann, ist der resultierende Wert des Bitfelds implementierungsdefiniert.
Falls target-expr und new-value überlappende Objekte identifizieren, ist das Verhalten undefiniert (es sei denn, die Überlappung ist exakt und der Typ identisch).
|
Wenn der Typ von target-expr volatile-qualifiziert ist, ist die Zuweisung als veraltet markiert, es sei denn, der (möglicherweise in Klammern gesetzte) Zuweisungsausdruck ist ein verworfen-wert Ausdruck oder ein nicht ausgewerteter Operand . |
(seit C++20) |
Zuweisung von einem Nicht-Ausdruck-Initialisierernew-value darf nur in folgenden Situationen kein Ausdruck sein:
#include <complex> std::complex<double> z; z = {1, 2}; // meaning z.operator=({1, 2}) z += {1, 2}; // meaning z.operator+=({1, 2}) int a, b; a = b = {1}; // meaning a = b = 1; a = {1} = b; // syntax error |
(seit C++11) |
Bei
Überlagerungsauflösung gegenüber benutzerdefinierten Operatoren
nehmen für jeden Typ
T
die folgenden Funktionssignaturen an der Überlagerungsauflösung teil:
|
T
*
&
operator
=
(
T
*
&
, T
*
)
;
|
||
|
T
*
volatile
&
operator
=
(
T
*
volatile
&
, T
*
)
;
|
||
Für jeden Aufzählungs- oder Zeiger-auf-Mitglied-Typ
T
, optional flüchtig qualifiziert, nimmt die folgende Funktionssignatur an der Überladungsauflösung teil:
|
T
&
operator
=
(
T
&
, T
)
;
|
||
Für jedes Paar
A1
und
A2
, wobei
A1
ein arithmetischer Typ (optional volatile-qualifiziert) und
A2
ein höhergestufter arithmetischer Typ ist, nimmt die folgende Funktionssignatur an der Überladungsauflösung teil:
|
A1
&
operator
=
(
A1
&
, A2
)
;
|
||
Eingebundener zusammengesetzter Zuweisungsoperator
Das Verhalten jedes eingebauten zusammengesetzten Zuweisungsausdrucks
target-expr
op
=
new-value
ist genau identisch mit dem Verhalten des Ausdrucks
target-expr
=
target-expr
op
new-value
, mit der Ausnahme, dass
target-expr
nur einmal ausgewertet wird.
Die Anforderungen an target-expr und new-value der eingebauten einfachen Zuweisungsoperatoren gelten ebenfalls. Darüber hinaus:
- Für + = und - = muss der Typ von target-expr ein arithmetischer Typ oder ein Zeiger auf einen (möglicherweise cv-qualifizierten) vollständig definierten Objekttyp sein.
- Für alle anderen zusammengesetzten Zuweisungsoperatoren muss der Typ von target-expr ein arithmetischer Typ sein.
Bei
Überlagerungsauflösung für benutzerdefinierte Operatoren
, für jedes Paar
A1
und
A2
, wobei
A1
ein arithmetischer Typ (optional volatile-qualifiziert) und
A2
ein höhergestufter arithmetischer Typ ist, nehmen die folgenden Funktionssignaturen an der Überlagerungsauflösung teil:
|
A1
&
operator
*
=
(
A1
&
, A2
)
;
|
||
|
A1
&
operator
/
=
(
A1
&
, A2
)
;
|
||
|
A1
&
operator
+
=
(
A1
&
, A2
)
;
|
||
|
A1
&
operator
-
=
(
A1
&
, A2
)
;
|
||
Für jedes Paar
I1
und
I2
, wobei
I1
ein integraler Typ (optional mit volatile-Qualifizierung) und
I2
ein gepromoteter integraler Typ ist, nehmen die folgenden Funktionssignaturen an der Überlagerungsauflösung teil:
|
I1
&
operator
%
=
(
I1
&
, I2
)
;
|
||
|
I1
&
operator
<<=
(
I1
&
, I2
)
;
|
||
|
I1
&
operator
>>=
(
I1
&
, I2
)
;
|
||
|
I1
&
operator
&
=
(
I1
&
, I2
)
;
|
||
|
I1
&
operator
^
=
(
I1
&
, I2
)
;
|
||
|
I1
&
operator
|
=
(
I1
&
, I2
)
;
|
||
Für jeden optional cv-qualifizierten Objekttyp
T
nehmen die folgenden Funktionssignaturen an der Überladungsauflösung teil:
|
T
*
&
operator
+
=
(
T
*
&
,
std::
ptrdiff_t
)
;
|
||
|
T
*
&
operator
-
=
(
T
*
&
,
std::
ptrdiff_t
)
;
|
||
|
T
*
volatile
&
operator
+
=
(
T
*
volatile
&
,
std::
ptrdiff_t
)
;
|
||
|
T
*
volatile
&
operator
-
=
(
T
*
volatile
&
,
std::
ptrdiff_t
)
;
|
||
Beispiel
#include <iostream> int main() { int n = 0; // keine Zuweisung n = 1; // direkte Zuweisung std::cout << n << ' '; n = {}; // Null-Initialisierung, dann Zuweisung std::cout << n << ' '; n = 'a'; // Ganzzahl-Höherstufung, dann Zuweisung std::cout << n << ' '; n = {'b'}; // explizite Typumwandlung, dann Zuweisung std::cout << n << ' '; n = 1.0; // Gleitkomma-Konvertierung, dann Zuweisung std::cout << n << ' '; // n = {1.0}; // Compiler-Fehler (verengende Konvertierung) int& r = n; // keine Zuweisung r = 2; // Zuweisung über Referenz std::cout << n << ' '; int* p; p = &n; // direkte Zuweisung p = nullptr; // Nullzeiger-Konvertierung, dann Zuweisung std::cout << p << ' '; struct { int a; std::string s; } obj; obj = {1, "abc"}; // Zuweisung von einer Initialisierungsliste std::cout << obj.a << ':' << obj.s << '\n'; }
Mögliche Ausgabe:
1 0 97 98 1 2 (nil) 1:abc
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| CWG 1527 | C++11 |
bei Zuweisungen an Klassentyp-Objekte konnte der rechte Operand
nur dann eine Initialisiererliste sein, wenn die Zuweisung durch einen benutzerdefinierten Zuweisungsoperator definiert war |
entfernte benutzerdefinierte
Zuweisungseinschränkung |
| CWG 1538 | C++11 |
E1
=
{
E2
}
war äquivalent zu
E1
=
T
(
E2
)
(
T
ist der Typ von
E1
), dies führte einen C-Stil-Cast ein
|
es ist äquivalent
zu E1 = T { E2 } |
| CWG 2654 | C++20 |
zusammengesetzte Zuweisungsoperatoren für volatile
-qualifizierte Typen wurden inkonsistent als veraltet markiert |
keiner von ihnen
ist veraltet |
| CWG 2768 | C++11 |
eine Zuweisung von einem Nicht-Ausdruck-Initialisierer
an einen Skalarwert würde Direct-List-Initialisierung durchführen |
führt stattdessen Copy-List-
Initialisierung durch |
| CWG 2901 | C++98 |
der Wert, der einem
unsigned
int
Objekt durch einen int Lvalue zugewiesen wird, war unklar |
klargestellt |
| P2327R1 | C++20 |
bitweise zusammengesetzte Zuweisungsoperatoren für volatile-Typen
wurden als veraltet markiert, obwohl sie für einige Plattformen nützlich sind |
sie sind nicht
veraltet |
Siehe auch
| Häufige Operatoren | ||||||
|---|---|---|---|---|---|---|
| Zuweisung |
Inkrement
Dekrement |
Arithmetik | Logisch | Vergleich |
Member
Zugriff |
Sonstige |
|
a
=
b
|
++
a
|
+
a
|
!
a
|
a
==
b
|
a
[
...
]
|
Funktionsaufruf
a ( ... ) |
|
Komma
a, b |
||||||
|
Bedingungsoperator
a ? b : c |
||||||
| Spezielle Operatoren | ||||||
|
static_cast
konvertiert einen Typ in einen anderen verwandten Typ
|
||||||
|
C-Dokumentation
für
Zuweisungsoperatoren
|