前置演算子と後置演算子の違い - C++ プログラミング

PROGRAM


前置演算子と後置演算子の違い

C++ で、ある変数 a に 1 の値を足すとき、次の 2 つの演算子を使うことができます。

++a;

a++;

前者のように、演算子を変数の前に持ってくるのを「前置演算子」、変数の後に持ってくるのを「後置演算子」といいます。

 

このように 2 つの書き方が存在するだけあって、その働きもわずかに違います。

これらの違いが表れてくるのは、このようにして演算した値を変数に代入するときです。

b = ++a;

c = a++;

変数 b には前置演算子を使って計算した値を代入していますが、このときの b の値は「a の値に 1 足し終わった後」の値になります。

変数 c には高知演算子を使って計算した値を代入していますが、このときの c の値は「a の値に 1 を足す前」の値になります。

そしてどちらの場合であっても、a の値は、元の値に 1 が足された値に更新されます。

 

前置演算子の方が効率が良い場合が多い

演算子は通常、"x = a + b" というように計算結果を代入したり、"a + b + c" というように続けて行けるように、計算結果を「値」または「参照」で返すようになっています。

値か参照かのどちらを取るかは、計算結果が新しい値であるなら「値」を新たに作って返すしかないですが、自分自身を更新した場合は自分自身の「参照」を返せば、新しい値を作らなくていい分、効率的です。

 

前置演算子 (++a) と後置演算子 (a++) とでは、ちょうどここの部分で明暗が分かれます。

まず、どちらの場合も自分自身の値が更新されるところは同じです。

そして重要なのが、前置演算子 (++a) の場合は「計算し終わった後」の値を返せばいいのに対して、後置演算子 (a++) の場合は「計算し終える前」の値を返さなくてはいけないところです。

 

どちらの場合も自分自身の値が更新されるので、最終的に自分自身は「計算し終わった後」の値になります。

そのため、前置演算子 (++a) であれば最後に自分自身の参照を返すだけで済みますが、後置演算子 (a++) の場合は計算前に値を複製しておいて、計算後にその複製しておいた値を返すということが必要になります。

 

具体的にコードで書くと次のような違いになります。

// 前置演算子 (++a) では、足し算をした後、自分自身の参照を返すだけで大丈夫です。

CMyClass& CMyClass::operator++()

{

// 自分の値を更新します。

this->m_value++;

 

// 自分自身の参照を返します。

return *this;

}

 

// 後置演算子 (a++) では、足し算をする前に、自分自身をコピーしておいて、最後にそれを値として返す必要があります。

CMyClass CMyClass::operator++(int)

{

// 現在の値をコピーコンストラクタで複製します。

CMyClass result = *this;

 

// 自分の値を更新します。

this->m_value++;

 

// 複製しておいた値を返します。このときにも、ムーブコンストラクタまたはコピーコンストラクタが呼び出されます。

return result;

}

このように、似たような演算をするにも、前置演算子と後置演算子とでは処理の重みがずいぶん違ってきます。

 

このような違いから、例えば for ループ などで演算子 "++" を使ってループカウンタを進めて行くような場合には、前置演算子 (++a) を使ってカウンタをインクリメントして行く方が、プログラムの効率が良くなることが一般的なようです。

後置演算子 (a++) を使う出番としては、「自分自身の値を更新しつつ、更新前の値を使って別のことをしたい」ような、特殊な場合に限られそうです。


[ もどる ]