• ベストアンサー

前置と後置

下記のようにfor文でインクリメントを先につけてる人をたまにみかけるのですが for( itr = m_v.begin() ; itr != m_v.end() ; ++itr ) for文でインクリメント(デクリメント)を先につけるのと後につけるので 結果が異なる場合ってありますか? 宜しくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

> >前置形のインクリメントの場合、演算を行うたびに一次オブジェクトが生成されます。 > No1の回答ですけどこれは、後置形の間違えですよね? 失礼。後置形の間違いでした。 > 後置形の場合は、組み込み型とおなじく前の値を返す為そういう定義をしているとの解釈で > 良いでしょうか はい、そうです。

sha-girl
質問者

お礼

非常に勉強になりました。 もしこの質問をしなければ、前置と後置の違いを当分知ることは無かったと思うと。。。 有難うございました。

その他の回答 (2)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

> それをうまく見せる方法は無いでしょうか。ためしに作ったのですがうまく > 違いをみることができません。 既存のクラスの場合は、逆アセンブルしてみるのが一番です。 自作の場合、 B& operator++() {  ++i;  cout << "インクリメント前" << i << endl;  return *this; } B operator++(int) {  B t(*this);  ++i;  cout << "インクリメント後" << i << endl;  return t; } のように定義することになります。 デフォルトコンストラクタとコピーコンストラクタが呼び出された際に、何らかのメッセージを出すようにすれば、様子が把握できると思います。

sha-girl
質問者

お礼

再度ご回答ありがとうございます。 おっしゃるとおり STLのvectorのiteratorのoperator++(int)の場合 iterator _Tmp = *this; ++*this; return _Tmp; となっていました。 >前置形のインクリメントの場合、演算を行うたびに一次オブジェクトが生成されます。 No1の回答ですけどこれは、後置形の間違えですよね? 後置形の場合は、組み込み型とおなじく前の値を返す為そういう定義をしているとの解釈で 良いでしょうか?

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

> for( itr = m_v.begin() ; itr != m_v.end() ; ++itr ) 上のようにイテレータの場合(というよりPOD以外の形の場合)、インクリメントを前置にするのと後置にするのでは明らかな違いがあります。 前置形のインクリメント(またはデクリメント)の場合、演算を行うたびに一次オブジェクトが生成されます。(実装にもよりますが、演算内部で1回、返却値でさらにもう1回の一次オブジェクトの生成・削除が行われます) 一次オブジェクトが生成・削除されると、それだけ無駄な処理が発生し、結果として効率が低下します。また、一次オブジェクト生成時に例外が発生する可能性も出てくるので、それだけ実行パスが複雑になります。 なお、組み込み型の場合は、前置でも後置でも特に違いはありません。また、テンプレートのように、組み込み型になるかどうか分からない場合には、前置形にしておいた方が無難です。

sha-girl
質問者

お礼

ご回答有難うございます。 >POD以外の形の場合、インクリメントを前置にするのと後置にするのでは明らかな違いがあります。 それをうまく見せる方法は無いでしょうか。ためしに作ったのですがうまく 違いをみることができません。 #include <iostream> using namespace std; class A { public: virtual int Get(){ return -1; } }; class B : public A { int i; public: B(){ i = 0; } ~B() { cout << "End" << endl; } int Get() {return i;} operator++(){ i++; cout << "インクリメント前" << i << endl; } operator++(int){ i++; cout << "インクリメント後" << i << endl; } }; int main() { B b1; for( ; b1.Get() < 10 ; b1++ ){ cout << b1.Get() << endl; } for( B b2 ; b2.Get() < 10 ; ++b2 ){ cout << b2.Get() << endl; } return 0; }

関連するQ&A