代入演算子
代入演算子はオブジェクトの値を変更します。
演算子名 | 構文 | オーバーロード可能 | プロトタイプの例 (class T に対して) | |
---|---|---|---|---|
クラス定義の内側 | クラス定義の外側 | |||
単純代入 | a = b
|
Yes | T& T::operator =(const T2& b); | N/A |
加算代入 | a += b
|
Yes | T& T::operator +=(const T2& b); | T& operator +=(T& a, const T2& b); |
減算代入 | a -= b
|
Yes | T& T::operator -=(const T2& b); | T& operator -=(T& a, const T2& b); |
乗算代入 | a *= b
|
Yes | T& T::operator *=(const T2& b); | T& operator *=(T& a, const T2& b); |
除算代入 | a /= b
|
Yes | T& T::operator /=(const T2& b); | T& operator /=(T& a, const T2& b); |
剰余代入 | a %= b
|
Yes | T& T::operator %=(const T2& b); | T& operator %=(T& a, const T2& b); |
ビット単位の論理積代入 | a &= b
|
Yes | T& T::operator &=(const T2& b); | T& operator &=(T& a, const T2& b); |
ビット単位の論理和代入 | a |= b
|
Yes | T& T::operator |=(const T2& b); | T& operator |=(T& a, const T2& b); |
ビット単位の排他的論理和代入 | a ^= b
|
Yes | T& T::operator ^=(const T2& b); | T& operator ^=(T& a, const T2& b); |
ビット単位の左シフト代入 | a <<= b
|
Yes | T& T::operator <<=(const T2& b); | T& operator <<=(T& a, const T2& b); |
ビット単位の右シフト代入 | a >>= b
|
Yes | T& T::operator >>=(const T2& b); | T& operator >>=(T& a, const T2& b); |
|
目次 |
[編集] 説明
コピー代入演算子はオブジェクト a
の内容を b
の内容で置き換えます (b
は変更されません)。 クラス型の場合、これは特別なメンバ関数であり、コピー代入演算子で説明されています。
ムーブ代入演算子はオブジェクト a
の内容を b
の内容で置き換えますが、可能であればコピーを回避します (b
は変更されるかもしれません)。 クラス型の場合、これは特別なメンバ関数であり、 ムーブ代入演算子で説明されています。 (C++11以上)
非クラス型の場合、コピー代入とムーブ代入は区別できず、直接代入と呼ばれます。
複合代入演算子は、オブジェクト a
の内容を、 a
の以前の値と b
の値の間の二項演算の結果で置き換えます。
[編集] 組み込みの直接代入
直接代入式は以下の形式を持ちます。
lhs = rhs
|
(1) | ||||||||
lhs = {}
|
(2) | (C++11以上) | |||||||
lhs = { rhs }
|
(3) | (C++11以上) | |||||||
組み込みの演算子の場合、 lhs は任意の非 const スカラー型を使用でき、 rhs は lhs の型に暗黙に変換可能でなければなりません。
直接代入演算子は左の被演算子として変更可能な左辺値を、右の被演算子として右辺値式または波括弧初期化子リスト (C++11以上)を期待し、変更後の左の被演算子を表す左辺値を返します。
非クラス型の場合、右の被演算子はまず左の被演算子の cv 修飾されていない型に暗黙に変換され、その後その値が左の被演算子の表すオブジェクトにコピーされます。
左の被演算子が参照型のとき、代入演算子はその参照先のオブジェクトを変更します。
左右の被演算子が表しているオブジェクトがオーバーラップしている場合、動作は未定義です (そのオーバーラップがぴったりで型が同じ場合を除きます)。
右の被演算子が波括弧初期化子リストの場合、
|
(C++11以上) |
ユーザ定義の演算子に対するオーバーロード解決において、すべての型 T
について、以下の関数シグネチャがオーバーロード解決に参加します。
T*& operator=(T*&, T*); |
||
T*volatile & operator=(T*volatile &, T*); |
||
すべての列挙型またはメンバポインタ型または volatile 修飾されたそれらの型 T
について、以下の関数シグネチャがオーバーロード解決に参加します。
T& operator=(T&, T ); |
||
A1 が算術型または volatile 修飾された算術型であり、 A2 が昇格された算術型であるような、 A1 と A2 のすべての組について、以下の関数シグネチャがオーバーロード解決に参加します。
A1& operator=(A1&, A2); |
||
[編集] 例
#include <iostream> int main() { int n = 0; // 代入ではない n = 1; // 直接代入 std::cout << n << ' '; n = {}; // ゼロ初期化して代入 std::cout << n << ' '; n = 'a'; // 整数昇格して代入 std::cout << n << ' '; n = {'b'}; // 明示的なキャストをして代入 std::cout << n << ' '; n = 1.0; // 浮動小数点変換して代入 std::cout << n << ' '; // n = {1.0}; // コンパイルエラー (縮小変換) int& r = n; // 代入ではない int* p; r = 2; // 参照を通した代入 std::cout << n << '\n'; p = &n; // 直接代入 p = nullptr; // ヌルポインタ変換して代入 struct {int a; std::string s;} obj; obj = {1, "abc"}; // 波括弧初期化子リストからの代入 std::cout << obj.a << ':' << obj.s << '\n'; }
出力:
1 0 97 98 1 2 1:abc
[編集] 組み込みの複合代入
組み込みの複合代入式は以下の形式を持ちます。
lhs op rhs | (1) | ||||||||
lhs op {} | (2) | (C++11以上) | |||||||
lhs op { rhs } | (3) | (C++11以上) | |||||||
op | - | *=, /= %=, += -=, <<=, >>=, &=, ^=, |= のいずれか |
lhs | - | 組み込みの演算子の場合、 lhs は任意の算術型を使用できます。 op が += または -= のときは、 + および - と同じ制限付きでポインタ型も使用できます。 |
rhs | - | 組み込みの演算子の場合、 rhs は lhs に暗黙に変換可能でなければなりません。 |
すべての組み込みの複合代入式 E1 op= E2 (ただし E1 は変更可能な左辺値式で、 E2 は右辺値式または波括弧初期化子リスト (C++11以上)) の動作は、式 E1 = E1 op E2 の動作と、式 E1
が一度しか評価されないことと、不定に配列される関数呼び出しに関して単一の操作として動作する (例えば f(a += b, g()) の場合、 += は g() の内部から見てまったく開始されていないか完了しているかのいずれかです) ことを除いて、まったく同じです。
ユーザ定義の演算子に対するオーバーロード解決において、 A1 が算術型または volatile 修飾された算術型であり、 A2 が昇格した算術型であるような、 A1 と A2 のすべての組について、以下の関数シグネチャがオーバーロード解決に参加します。
A1& operator*=(A1&, A2); |
||
A1& operator/=(A1&, A2); |
||
A1& operator+=(A1&, A2); |
||
A1& operator-=(A1&, A2); |
||
I1 が整数型または volatile 修飾された整数型であり、 I2 が昇格した整数型であるような、 I1 と I2 のすべての組について、以下の関数シグネチャがオーバーロード解決に参加します。
I1& operator%=(I1&, I2); |
||
I1& operator<<=(I1&, I2); |
||
I1& operator>>=(I1&, I2); |
||
I1& operator&=(I1&, I2); |
||
I1& operator^=(I1&, I2); |
||
I1& operator|=(I1&, I2); |
||
オブジェクト型または cv 修飾されたオブジェクト型 T
について、以下の関数シグネチャがオーバーロード解決に参加します。
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); |
||
[編集] 例
This section is incomplete Reason: no example |
[編集] 関連項目
一般的な演算子 | ||||||
---|---|---|---|---|---|---|
代入 | インクリメント デクリメント |
算術 | 論理 | 比較 | メンバアクセス | その他 |
a = b |
++a |
+a |
!a |
a == b |
a[b] |
a(...) |
特殊な演算子 | ||||||
static_cast は型を別の関連する型に変換します。 |
代入演算子 の C言語リファレンス
|