- ベストアンサー
C++ メンバ配列の初期化
------------------------------------------- class Myclass { int array[20]; public: Myclass() { for(int i=0; i<20; i++) { array[i] = 0; } } }; -------------------------------------------- ↑のようにするとarrayが初期化ではなく、代入されるそうなんですが、何か良い初期化方法があれば教えてください。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
memsetによる初期化はいろいろ問題があるのでお勧めしませんが、int型の配列であれば実害はないので、状況次第では使ってもよいでしょう。 効率に関してですが、memsetの一般的な実装では、前後の半端を除けば、ワード単位で書き込みを行います。あるいは、ストリング命令やブロック転送命令があるプロセッサの場合は、最も効率のよいコードに展開されます(関数の呼び出しも発生しません)。 std::fillやstd::fill_nを使うと関数呼び出しのオーバーヘッドは発生しますので、効率のことをいうのであれば必ずしも最適ではありません。ただ、普通は一番よい選択だと思います。 いっそのこと、 class MyClass { struct Member { int array[20]; } m; public: MyClass() : m(Member()) {} }; のようにするのもよいと思います。 memsetよりはずっと健全ですし、STLが使えない場合でも大丈夫ですし、おそらくコンパイラは最も効率の良いコードを出力すると思います。
その他の回答 (4)
- bluecampus
- ベストアンサー率66% (138/209)
STLのfill_nはどうでしょうか。 #include <algorithm> std::fill_n(array, _countof(array), 0);
お礼
目からウロコです。ありがとうございます。
- Lchan0211
- ベストアンサー率64% (239/371)
処理系にもよりますが、この場合memsetの方が速いというのは幻想だと思います。 結局memset関数の中で、ループしてメモリを初期化しています。 しかも、memsetは、バイト単位の初期化になるため、 int20個の初期化は80回ループになります。 memset関数を呼び出すための関数呼び出しオーバーヘッドもあります。 処理系によっては、memsetをインラインで最適化して 処理してしまうケースもあると思いますが、 結局、質問に書かれているコーディングの通り、 int型変数(32ビット領域)に0を代入する処理を20回繰り返す処理を記述するのが 性能的に最も最適化されたコーディングだと思います。 ただ、memsetで初期化処理を記述する方がわかりやすいので、 メンテナンス性を考慮して、memsetにすべきという意見はあると 思います。私も特に性能を考慮する必要がない限りmemsetを使います。 今回のケースは、たいして複雑な初期化でもないし、 性能差もnsecレベルの話だと思うので、どちらでもよいと思います。
お礼
詳しく説明していただき分かりやすいです。参考になります。
- toda hiro(@hiro_knigh)
- ベストアンサー率39% (59/151)
別に良いと思いますが、少しでも実行速度を上げたい場合は、mensetの方が良いと思います。 (自分でfor文で初期化すると少し実行速度が落ちます。) memset(array,0,sizeof(array));
お礼
ご回答ありがとうございます。勉強になります。 memsetはレジスタでも使ってるんですかね?そのうち調べてみたいと思います。
- jacta
- ベストアンサー率26% (845/3158)
int型の配列であれば、代入になっても大差はないので、そのままでもよいのではないでしょうか?
お礼
私の中ではこのやり方に迷いが会ったのですが、おかげ様で自信が持てました。ありがとうございます。
お礼
難しいですが面白い話です。ありがとうございます。