2005年9月25日日曜日

プログラミング言語の比較(2回目)

★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();
CやJAVAしか知らない状態で見ると、シフト演算を行っているかのように見えますが、C++では演算子のオーバーロードが可能な為、これでコピーが行われます。
実際には以下の記述と同義です。
 out.operator<<(in.rdbuf());

オーバーロードは、直感的な判り易さを与えます。この例では、「inの内容をoutに入れる(コピーする)」と言った所でしょうか。

▽リソースの解放
さて、Cのプログラムと見比べると、ファイルをクローズする処理がありません。一体、どうなっているのでしょうか?
C++ではクラスと呼ばれるデータ構造が登場します。ファイル操作をしている、ifstreamやofstreamもクラスです。
さらに、クラスにはデストラクタと呼ばれる、メモリ上に構築されたクラスが破棄される直前に実行される(メンバ)関数があります。
ifstreamやofstreamクラスのデストラクタでは、開いているファイルをクローズする処理が行われるので、このクラスを使用した場合、プログラマによる明示的なクロー ズは不要です。(auto変数でない場合、クラス自体の明示的な削除が必要になるのですが、それに付いての説明は割愛します)

次回は、JAVAです。