★C++で作成
今回はC++ですね。
かなり間が空いてしまったので、早速行きましょう。
#include #include #include #include using namespace std; void execute(char* src, char* dest) throw (ios_base::failure) { const int buffer_size = 2048; char buffer[buffer_size]; // ファイルオープン ifstream in(src, ios_base::in | ios_base::binary); if(!in.is_open()) { throw ios_base::failure(src); } ofstream out(dest, ios_base::out | ios_base::binary | ios_base::trunc); if(!out.is_open()) { throw ios_base::failure(dest); } // ストリームのバッファサイズ指定 in.rdbuf()->pubsetbuf(0, buffer_size); out.rdbuf()->pubsetbuf(0, buffer_size); // コピー実行 out << in.rdbuf(); } int main(int argc, char** args) { if(argc < 3) { cout << args[0] << " [コピー元ファイルパス] [コピー先ファイルパス]" << endl; return 0; } else if(!strcmp(args[1], args[2])) { cout << "コピー元とコピー先が同じです。" << endl; return 1; } int start = clock(); try { execute(args[1], args[2]); } catch(const ios_base::failure& e) { cout << e.what() << " ファイルが見つかりません。" << endl; return 1; } int end = clock(); cout << (end - start)/1000.0 << " 秒経過" << endl; return 0; } |
関数の構成・処理順序は、他の言語で作成した物と比べ易いように極力似せて作っています。
但し、そうは言っても違う所は当然あるので、以下の項目をちょっとだけ見てみましょう。(CとC++の違いを全て説明すると趣旨が曖昧になるので、C++に関して詳しく知りたければ、こちらへ)
- 例外処理機構
- 演算子のオーバーロード
- リソースの解放
▽例外処理機構
main関数から execute関数を呼び出す前後にtry-catch文、execute関数ではthrow文があります。これが例外処理機構です。
例外処理機構では、エラーが発生した場合、エラー発生箇所からエラー処理部分まで一気に処理を移す事が可能です。
(これにより、処理成否を判定するif文のネストや、エラー処理部分まで処理を飛ばす為のgoto文を削減する事が出来ます)
▽演算子のオーバーロード
ファイルのコピーを以下の1行で行っています。
out << in.rdbuf(); |
実際には以下の記述と同義です。
out.operator<<(in.rdbuf()); |
オーバーロードは、直感的な判り易さを与えます。この例では、「inの内容をoutに入れる(コピーする)」と言った所でしょうか。
▽リソースの解放
さて、Cのプログラムと見比べると、ファイルをクローズする処理がありません。一体、どうなっているのでしょうか?
C++ではクラスと呼ばれるデータ構造が登場します。ファイル操作をしている、ifstreamやofstreamもクラスです。
さらに、クラスにはデストラクタと呼ばれる、メモリ上に構築されたクラスが破棄される直前に実行される(メンバ)関数があります。
ifstreamやofstreamクラスのデストラクタでは、開いているファイルをクローズする処理が行われるので、このクラスを使用した場合、プログラマによる明示的なクロー ズは不要です。(auto変数でない場合、クラス自体の明示的な削除が必要になるのですが、それに付いての説明は割愛します)
次回は、JAVAです。