Garbage Collection

塵も積もれば山

目次

Blog 利用状況

ニュース

C++とかC#とか数学ネタを投下していく予定です。

[その他のページ]
日々の四方山話を綴った日記出水の日記帳

書庫

日記カテゴリ

[C++]クラスコンストラクト

以前、メンバ関数にもconstをつけようよ、という話を書きました。
[c++]貸すだけなんだから、汚さないでよね!

で、思い出したこんな話。

class File{
  FILE* fp;
public:
  int open(const char *path, const char *mode){fp = fopen(path, mode); return fp == NULL;}
  int close(){return fclose(fp);}
  int read(void *ptr, size_t size, size_t nmemb){return fread(ptr, size, nmemb);}
  int write(const void *ptr, size_t size, size_t nmemb){return fwrite(ptr, size, nmemb);}
  int eof(){return feof(fp);}
  int seek(int offset, int whence)){return fseek(fp, offset, whence);}
  int tell()){return ftell(fp);}
};

ファイルのラッパクラスを作りました。
エラー処理やら型が違うやらいわれそうですが、その辺は置いておきます。

今回の話は、この中のどのメンバ関数にconstをつけるべきか、という話です。

constをつけるとメンバー変数の書き換えから保護されます。
上記のクラスの場合、open関数はメンバ変数fpを書き換えているので、
open関数にconstをつけるとコンパイルエラーがでます。

なお、open関数以外はconstをつけてもエラーが出ません。
実際、こんな感じでopen関数以外はすべてconstがついているソースがあったわけです。

私の考えだと、つけてもよいのはeofとtellだけです。
理由は、これらの関数はfpの先をも書き換えてないと推測できるからです。
推測というのが若干弱いですが。

まぁ、現在だとconstすらついてないというのが多いのでこんなことになっているのは少数ですが、
エラーが出ない限りつければいい、ってもんじゃないんだってことです。

投稿日時 : 2009年7月30日 10:55

Feedback

# re: [C++]クラスコンストラクト 2009/07/30 12:44 アキラ

ファイルのラッパクラスって、使う側としては
Load()関数、Save()関数とかのなかでローカル変数として使うことが多いと思うので
const付いても付いてなくてもどっちでもいいかも。
(IOは副作用あるし・・・んー。)

ただ、Load()/Save()がメンバ関数ならLoad()は非const、Save()はconstにします。

# re: [C++]クラスコンストラクト 2009/07/30 12:48 アキラ

念のため補足。

> Load()関数、Save()関数とかのなかでローカル変数として使うことが多いと思うので

ちょっとずつ読む/書くとかしなければ。


> (IOは副作用あるし・・・んー。)

副作用あるからconst付けないほうがいいかも、と書きたかった(^^;

# re: [C++]クラスコンストラクト 2009/07/30 13:50 774RR

プログラマから見えないところに副作用があるのはどれも同じなので
いっそのこと全部 const つけて FILE* fp を mutable に・・・嘘

この例の場合代入・コピー禁止文脈をつけておかないとはまりますな。

# re: [C++]クラスコンストラクト 2009/07/30 18:43 びーしむ

const が付いてるべきところにconstがなくって
エラーになるパターンのほうが多いので、
自分は const が付けられるとこには全部つけといて欲しい派です。
ですが、このようなラッパクラスでは、元の操作の条件を反映するほうが良いですね。

# re: [C++]クラスコンストラクト 2009/07/31 1:15 出水

まぁ、これは実際の例ではないので…

今回のような例はあえてどの関数にもconstをつけずに
constをつけた運用禁止、というのもありかもですね
実際、何を保護しているのかわからなくなりますし

タイトル
名前
Url
コメント