構文
expression
assignment-operator
expression
assignment-operator: 次のいずれか
= *= /= %= += -= <<= >>= &= ^= |=
注釈
代入演算子は、左オペランドで指定されたオブジェクトに値を格納します。 割り当て操作には、次の 2 種類があります。
単純代入。2 番目のオペランドの値が、最初のオペランドで指定されたオブジェクトに格納されます。
複合代入。結果を格納する前に算術演算、シフト演算、またはビットごとの演算が実行されます。
=演算子を除く、次の表のすべての代入演算子は複合代入演算子です。
代入演算子テーブル
| オペレーター | 意味 |
|---|---|
= |
2 番目のオペランドの値を、最初のオペランドで指定されたオブジェクトに格納します (単純代入)。 |
*= |
最初のオペランドの値に 2 番目のオペランドの値を乗算します。は、最初のオペランドで指定されたオブジェクトに結果を格納します。 |
/= |
最初のオペランドの値を 2 番目のオペランドの値で除算します。は、最初のオペランドで指定されたオブジェクトに結果を格納します。 |
%= |
2 番目のオペランドの値で指定された最初のオペランドの剰余を取ります。は、最初のオペランドで指定されたオブジェクトに結果を格納します。 |
+= |
2 番目のオペランドの値を最初のオペランドの値に追加します。は、最初のオペランドで指定されたオブジェクトに結果を格納します。 |
-= |
2 番目のオペランドの値を最初のオペランドの値から減算します。は、最初のオペランドで指定されたオブジェクトに結果を格納します。 |
<<= |
最初のオペランドの値を、2 番目のオペランドの値で指定されたビット数のままにシフトします。は、最初のオペランドで指定されたオブジェクトに結果を格納します。 |
>>= |
最初のオペランドの値を、2 番目のオペランドの値で指定されたビット数だけ右にシフトします。は、最初のオペランドで指定されたオブジェクトに結果を格納します。 |
&= |
1 番目と 2 番目のオペランドのビットごとの AND を取得します。は、最初のオペランドで指定されたオブジェクトに結果を格納します。 |
^= |
1 番目と 2 番目のオペランドのビットごとの排他的 OR を取得します。は、最初のオペランドで指定されたオブジェクトに結果を格納します。 |
|= |
1 番目と 2 番目のオペランドのビットごとの包括 OR を取得します。は、最初のオペランドで指定されたオブジェクトに結果を格納します。 |
演算子キーワード
複合代入演算子のうち 3 つには、同等のキーワードがあります。 これらは次のとおりです。
| オペレーター | 同等の |
|---|---|
&= |
and_eq |
|= |
or_eq |
^= |
xor_eq |
C++ では、複合代入演算子の代替スペルとして、これらの演算子キーワードを指定します。 C では、代替スペルは <iso646.h> ヘッダーのマクロとして提供されます。 C++ では、代替スペルはキーワードです。 <iso646.h> または C++ と同等の <ciso646> の使用は非推奨です。 Microsoft C++ では、代替スペル チェックを有効にするには、 /permissive- または /Za コンパイラ オプションが必要です。
例
// expre_Assignment_Operators.cpp
// compile with: /EHsc
// Demonstrate assignment operators
#include <iostream>
using namespace std;
int main() {
int a = 3, b = 6, c = 10, d = 0xAAAA, e = 0x5555;
a += b; // a is 9
b %= a; // b is 6
c >>= 1; // c is 5
d |= e; // Bitwise--d is 0xFFFF
cout << "a = 3, b = 6, c = 10, d = 0xAAAA, e = 0x5555" << endl
<< "a += b yields " << a << endl
<< "b %= a yields " << b << endl
<< "c >>= 1 yields " << c << endl
<< "d |= e yields " << hex << d << endl;
}
単純な割り当て
単純代入演算子 (=) により、2 番目のオペランドの値が、最初のオペランドで指定されたオブジェクトに格納されます。 両方のオブジェクトが算術型の場合、右オペランドは値を格納する前に左の型に変換されます。
const型とvolatile型のオブジェクトは、volatileのみ、またはconstまたはvolatileではない型の l 値に割り当てることができます。
クラス型 (struct、 union、および class 型) のオブジェクトへの割り当ては、 operator=という名前の関数によって実行されます。 この演算子関数の既定の動作は、オブジェクトの非静的データ メンバーと直接基底クラスのメンバーごとのコピー割り当てを実行することです。ただし、この動作はオーバーロードされた演算子を使用して変更できます。 詳細については、「演算子の オーバーロード」を参照してください。 クラス型には 、コピー割り当て 演算子と 移動代入 演算子を含めることもできます。 詳細については、「 コピー コンストラクターとコピー代入演算子」および 「 Move コンストラクター」および「移動代入演算子」を参照してください。
特定の基底クラスから明確に派生したクラスのオブジェクトを、基底クラスのオブジェクトに割り当てることができます。 派生クラスから基底クラスへの暗黙的な変換がありますが、基底クラスから派生クラスへの暗黙的な変換はないため、逆は当てはまりません。 例えば次が挙げられます。
// expre_SimpleAssignment.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
class ABase
{
public:
ABase() { cout << "constructing ABase\n"; }
};
class ADerived : public ABase
{
public:
ADerived() { cout << "constructing ADerived\n"; }
};
int main()
{
ABase aBase;
ADerived aDerived;
aBase = aDerived; // OK
aDerived = aBase; // C2679
}
参照型への割り当ては、参照がポイントするオブジェクトに対して割り当てが行われているかのように動作します。
クラス型オブジェクトの場合、割り当ては初期化とは異なります。 さまざまな割り当てと初期化の方法を説明するには、コードを検討してください
UserType1 A;
UserType2 B = A;
上記のコードは初期化子を示しています。UserType1型の引数を受け取るUserType2のコンストラクターを呼び出します。 コードを指定した場合
UserType1 A;
UserType2 B;
B = A;
代入ステートメント
B = A;
は、次のいずれかの効果を持つことができます。
operator=にUserType1引数が指定されている場合は、UserType2の関数operator=を呼び出します。このような関数が存在する場合は、明示的な変換関数
UserType1::operator UserType2を呼び出します。このようなコンストラクターが存在する場合は、
UserType1引数を受け取って結果をコピーするコンストラクターUserType2::UserType2を呼び出します。
複合代入。
複合代入演算子は、 代入演算子の表に示されています。 これらの演算子の形式は e1op= e2 で、 e1 はconst 変更不可能な l 値で 、e2 は次のようになります。
算術型
ポインター (op が
+または-e1 の型に一致する
operator *op*=オーバーロードが存在する型
組み込みの e1op= e2 形式は e1=e1ope2 として動作しますが、 e1 は 1 回だけ評価されます。
列挙型への複合代入では、エラー メッセージが生成されます。 左オペランドがポインター型の場合、右オペランドはポインター型であるか、0 に評価される定数式である必要があります。 左オペランドが整数型の場合、右オペランドはポインター型にすることはできません。
組み込みの代入演算子の結果
組み込みの代入演算子は、代入の後に左オペランドで指定されたオブジェクトの値 (および複合代入演算子の場合は算術/論理演算) を返します。 結果の型は左オペランドの型です。 代入式の結果は常に l 値です。 これらの演算子には、右から左への結合規則があります。 左オペランドは変更可能な l 値である必要があります。
ANSI C では、代入式の結果は l 値ではありません。 つまり、有効な C++ 式 (a += b) += c は C では許可されません。