代入演算子

構文

expression assignment-operator expression

assignment-operator: 次のいずれか
=*=/=%=+=-=<<=>>=&=^=|=

解説

代入演算子は、左側のオペランドによって指定されたオブジェクトに値を格納します。 割り当て操作には、次の 2 種類があります。

  • 単純な代入。2 番目のオペランドの値は、1 番目のオペランドで指定されたオブジェクトに格納されます。

  • 複合代入。結果を格納する前に、算術演算、シフト演算、またはビットごとの演算が実行されます。

次の表の = 演算子を除くすべての代入演算子は、複合代入演算子です。

代入演算子の表

演算子 意味
= 1 番目のオペランドで指定されたオブジェクトに、2 番目のオペランドの値を格納します (単純代入)。
*= 1 番目のオペランドの値に 2 番目のオペランドの値を乗算します。結果を 1 番目のオペランドで指定されたオブジェクトに格納します。
/= 1 番目のオペランドの値を 2 番目のオペランドの値で除算します。結果を 1 番目のオペランドで指定されたオブジェクトに格納します。
%= 2 番目のオペランドの値による 1 番目のオペランドの剰余を得ます。結果を 1 番目のオペランドで指定されたオブジェクトに格納します。
+= 2 番目のオペランドの値を 1 番目のオペランドの値に加算します。結果を 1 番目のオペランドで指定されたオブジェクトに格納します。
-= 1 番目のオペランドの値から 2 番目のオペランドの値を減算します。結果を 1 番目のオペランドで指定されたオブジェクトに格納します。
<<= 1 番目のオペランドの値を 2 番目のオペランドの値で指定されたビット数の分だけ左にシフトします。結果を 1 番目のオペランドで指定されたオブジェクトに格納します。
>>= 1 番目のオペランドの値を 2 番目のオペランドの値で指定されたビット数の分だけ右にシフトします。結果を 1 番目のオペランドで指定されたオブジェクトに格納します。
&= 1 番目と 2 番目のオペランドのビットごとの AND を取得します。結果を 1 番目のオペランドで指定されたオブジェクトに格納します。
^= 1 番目と 2 番目のオペランドのビットごとの排他的 OR を取得します。結果を 1 番目のオペランドで指定されたオブジェクトに格納します。
|= 1 番目と 2 番目のオペランドのビットごとの包括的 OR を取得します。結果を 1 番目のオペランドで指定されたオブジェクトに格納します。

演算子のキーワード

複合代入演算子のうち 3 つは、キーワードに相当します。 これらは次のとおりです。

Operator 同等の
&= 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;
}

単純代入

単純代入演算子 (=) では、第 1 のオペランドによって指定されたオブジェクトに、第 2 のオペランドの値が保存されます。 両方のオブジェクトが数値型である場合、値を保存する前に、右側のオペランドが左側の型に変換されます。

const 型および volatile 型のオブジェクトは、volatile だけの型の左辺値、または const または volatile ではない型の左辺値に割り当てることができます。

クラス型 (struct 型、union 型、および class 型) のオブジェクトへの代入は、operator= という名前の関数によって行われます。 この演算子関数の既定の動作は、オブジェクトの非静的データ メンバーと直接基底クラスのメンバーごとのコピー割り当てを実行することです。ただし、この動作はオーバーロードされた演算子を使用して変更できます。 詳細については、「演算子のオーバーロード」を参照してください。 クラス型には、コピー代入演算子と移動代入演算子を含めることもできます。 詳細については、「コピー コンストラクターとコピー代入演算子」と「移動コンストラクターおよび移動代入演算子」を参照してください。

特定の基底クラスからの任意の明確な派生クラスのオブジェクトは、その基底クラスのオブジェクトに代入できます。 派生クラスから基底クラスへの暗黙の変換は存在しますが、基底クラスから派生クラスへの暗黙の変換は存在しないため、逆は当てはまりません。 次に例を示します。

// 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;

前のコードは初期化子を示すもので、型 UserType2 の引数をとる UserType1 のコンストラクターを呼び出します。 次のコードでは

UserType1 A;
UserType2 B;

B = A;

代入ステートメント

B = A;

には、次のいずれかの影響が考えられます。

  • UserType2 に対して operator= 関数を呼び出します。operator= には、UserType1 引数を提供します。

  • 明示的な変換関数 UserType1::operator UserType2 を呼び出します (そのような関数が存在する場合)。

  • UserType2::UserType2 引数を取り、結果をコピーする UserType1 コンストラクターを呼び出します (そのようなコンストラクターが存在する場合)。

複合代入

複合代入演算子は、代入演算子の表に示されています。 これらの演算子の形式は e1op= e2 です。ここで、e1 は変更できないconst左辺値で、e2 は次のようになります。

  • 数値型

  • op+ または - の場合は、ポインター

  • e1 の型に一致する operator *op*= オーバーロードが存在する型

組み込みの e1op= e2 の形式は e1=e1ope2 として動作しますが、e1 は 1 回だけ評価されます。

列挙型への複合代入によってエラー メッセージが生成されます。 左のオペランドがポインター型である場合、右のオペランドはポインター型であるか、0 に評価される定数式でなければなりません。 左のオペランドが整数型である場合、右のオペランドをポインター型にすることはできません。

組み込み代入演算子の結果

組み込みの代入演算子は、代入 (および複合代入演算子の場合は算術/論理演算) の後に左オペランドで指定されたオブジェクトの値を返します。 結果の型は左側のオペランドの型です。 代入式の結果は常に左辺値です。 これらの演算子の結合規則は、右から左方向です。 左のオペランドは、変更可能な左辺値である必要があります。

ANSI C では、代入式の結果は左辺値ではありません。 つまり、C では、有効な C++ 式 (a += b) += c は許可されません。

関連項目

2 項演算子を含む式
C++ の組み込み演算子、優先順位、結合規則
C の代入演算子