Namespaces
Variants

Assignment operators

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

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 ) ;
Hinweise
  • Alle integrierten Zuweisungsoperatoren geben * this zurück, und die meisten benutzerdefinierten Überladungen geben ebenfalls * this zurück, damit die benutzerdefinierten Operatoren auf die gleiche Weise wie die integrierten verwendet werden können. Allerdings kann bei einer benutzerdefinierten Operatorüberladung jeder Typ als Rückgabetyp verwendet werden (einschließlich void ).
  • T2 kann jeder Typ einschließlich T sein.

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
  1. target-expr muss eine höhere Präzedenz als ein Zuweisungsausdruck haben.
  2. new-value kann kein Komma-Ausdruck sein, da dessen Präzedenz niedriger ist.
1) Einfacher Zuweisungsausdruck.
2) Zusammengesetzter Zuweisungsausdruck.

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-Initialisierer

new-value darf nur in folgenden Situationen kein Ausdruck sein:

  • target-expr ist von einem skalaren Typ T , und new-value ist leer oder hat nur ein Element. In diesem Fall, mit einer erfundenen Variable t deklariert und initialisiert als T t = new-value  , ist die Bedeutung von x = new-value  gleich x = t .
  • target-expr ist von Klassentyp. In diesem Fall wird new-value als Argument an die durch Überladungsauflösung ausgewählte Zuweisungsoperatorfunktion übergeben.
#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 ) ;
**Anmerkung:** Der gesamte Inhalt innerhalb der ` ` Tags ist C++-Code und wurde gemäß den Anweisungen nicht übersetzt. Die HTML-Struktur und alle Tags wurden original beibehalten.

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 ) ;
**Anmerkung:** Da der gesamte Inhalt innerhalb von ` ` Tags liegt (was als Code-ähnliche Umgebung betrachtet werden kann) und gemäß den Anweisungen C++-spezifische Begriffe sowie Code nicht übersetzt werden sollen, bleibt der gesamte Inhalt unverändert. Die HTML-Struktur und Formatierung wurden vollständig beibehalten.

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

Operator-Präzedenz

Operatorüberladung

Häufige Operatoren
Zuweisung Inkrement
Dekrement
Arithmetik Logisch Vergleich Member
Zugriff
Sonstige

a = b
a + = b
a - = b
a * = b
a / = b
a % = b
a & = b
a | = b
a ^ = b
a <<= b
a >>= b

++ a
-- a
a ++
a --

+ a
- a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

! a
a && b
a || b

a == b
a ! = b
a < b
a > b
a <= b
a >= b
a <=> b

a [ ... ]
* a
& a
a - > b
a. b
a - > * b
a. * b

Funktionsaufruf

a ( ... )
Komma

a, b
Bedingungsoperator

a ? b : c
Spezielle Operatoren

static_cast konvertiert einen Typ in einen anderen verwandten Typ
dynamic_cast konvertiert innerhalb von Vererbungshierarchien
const_cast fügt cv -Qualifizierer hinzu oder entfernt sie
reinterpret_cast konvertiert Typ zu einem unverwandten Typ
C-style cast konvertiert einen Typ zu einem anderen durch eine Kombination von static_cast , const_cast und reinterpret_cast
new erstellt Objekte mit dynamischer Speicherdauer
delete zerstört zuvor durch den new-Ausdruck erstellte Objekte und gibt den bezogenen Speicherbereich frei
sizeof fragt die Größe eines Typs ab
sizeof... fragt die Größe eines pack ab (since C++11)
typeid fragt die Typinformationen eines Typs ab
noexcept prüft, ob ein Ausdruck eine Exception werfen kann (since C++11)
alignof fragt die Ausrichtungsanforderungen eines Typs ab (since C++11)

C-Dokumentation für Zuweisungsoperatoren