ifstreamのoperator=

[戻る]
reshia [HomePage] 2005/01/20(木) 13:08:15
いつも御世話になっています。

ifstreamを使って、
ifstream ifs;
ifs.open("HOGE.DAT");
という感じで、正常にファイルをオープンできたとします。

このとき、このifsをあるクラスAに渡して、
Aクラス内でifsを使ってファイル操作をしたかったのですが、
クラスA側のデータメンバ「ifstream _ifsA」にifsを代入しようとしても
「ifstrea::operator=」がprivateですので、使えません。

毎回毎回、関数の引数に参照渡しするのも面倒なので、
何か方法があれば教えて下さい。

REE 2005/01/20(木) 13:13:07
クラスA側のデータメンバをポインタにするのはどうですか?

reshia [HomePage] 2005/01/20(木) 13:16:08
あぁ、なるほど。
ちょっと試してみます。

reshia [HomePage] 2005/01/20(木) 13:52:46
[[解決]]
できました。ありがとうございます。
普段、ポインタ使ってないので思いつかなかったです。

やっててよくわからなかったのが、始め、
ofstream *_ofs;

void CHoge::Init(ofstream &ofs)
{
  _ofs = &ofs;
}
として、参照で渡ってきたofstreamのオブジェクトを
ofstreamのポインタに代入するために「&ofs」としたのですが、
(たぶん、このせいで)プログラムの途中、
_ofsを使い終わった後、(クラスから抜けた後かもしれませんが、)
にセグメンテーション違反が起きたのですが…

もう一度試してみると、発生しませんでした……
なんだったのでしょうか。
(答えてもらわなくてもいいですが)

reshia [HomePage] 2005/01/20(木) 13:53:58
あ、_ofsに出力してるときは、
*_ofs << "夏はビールだ!\n"
のようにしています。

monkey 2005/01/20(木) 14:06:19
> 毎回毎回、関数の引数に参照渡しする

私はこの方法で悪くないと思いますよ。
あるいは、仕様が許すならば、ifsをAクラスのデータメンバとし、ファイルオープン処
理をAクラスのメンバ関数で行う方法もあります。

ポインタは、指している先にオブジェクトが存在するかどうかをきちんと管理しなけれ
ばならず、プログラムの複雑さが増す傾向があり、なおさら「面倒」になる可能性があ
るからです。
ポインタは、他の解決法がどうしてもない時の最後の手段として考えた方が良いと思い
ます。

tetrapod 2005/01/20(木) 14:20:30
basic_*stream は代入できないよう設計されている (operator= が private) ので、
こういう場合の常套手段はこんな感じ。

class A {
   istream& is;
public:
   A(istream& is0) : is(is0) { ... }
   void read() { is >> something; }
};
引数が ifstream ではなく istream なのがミソ。
こうしておけば ifstream だろうが istringstream だろうが統一的に扱える。

# んでこの class A を template<class charT, class Traits> class A に
# istream を basic_istream にすればもっと完璧。

reshia [HomePage] 2005/01/20(木) 14:21:50
なるほど。勉強になります。
まだ学生ですから、仕様を作るのも自分ですので心配在りません。

オープンをAクラスでしても、実は、また別のBクラスでも使用、
つまり3つのクラスから参照するようなことになっていますので(これが問題か)
参照渡ししていくか、ポインタを使うしかないような気もします。

reshia [HomePage] 2005/01/20(木) 14:24:44
tetrapodさん、ありがとうございます。
やってみます。

tetrapod 2005/01/20(木) 14:36:17
っと、むしろこっちのほうが自然かもしれない。

ostream& operator<<(ostream& os, const A& a) { ...; return os; }
# 必要なら friend して。
こーすると A a; cout << a; のように書けます。

なにがやりたいかで適切な解は違うと思われます。

古いスレッドには追加発言できません。