←検索窓の楽しみ方
  ショッピングモール  掲示板ランキング


【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら



 本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール   掲示板1こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.3680

オブジェクトをファイルに出力
投稿者---kaz(2005/04/23 14:26:55)


お世話になります。C++でオブジェクトをファイルに出力する方法をさがしているのですが、(JAVAのObjectOutputStreamのようなもの)STLライブラリにはこのようなのはふくまれてないのでしょうか?実現する方法を教えてください。


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:オブジェクトをファイルに出力 3681 monkey 2005/04/23 14:55:04


No.3681

Re:オブジェクトをファイルに出力
投稿者---monkey(2005/04/23 14:55:04)


ofstreamクラスを使います。
(標準ライブラリヘッダファイル名<fstream>)


この投稿にコメントする

削除パスワード

No.3682

Re:オブジェクトをファイルに出力
投稿者---kaz(2005/04/23 16:10:32)


回答ありがとうございます。ofstreamについてしらべているのですが、普通にテキストに出力する例ばかりでオブジェクトをそのままバイナリーに保存している例がみつからないのですが、普通に書き出せばいいのでしょうか?
それから、もしクラスAの中にクラスBのメンバ変数があるとして、クラスAのオブジェクトを書き出したとして、クラスBのなかのメンバ変数なども普通に保存されるのでしょうか?JAVAのようにSelializableを継承しなければならないなどの制約がありましたら教えてください。よろしくおねがいします。


この投稿にコメントする

削除パスワード

No.3683

Re:オブジェクトをファイルに出力
投稿者---Ban(2005/04/23 16:56:02)


バイナリ書き出しだけなら、専用の operator << を用意するなり、
ofstream::write 等で書き出すなりでOkです。

ただし、懸念されているように、単純にバイナリデータが書かれる
だけですので、ポインタの内包とか、継承して多態とかしてると
そのままでは復元できません。

C++ には、シリアライズ/デシリアライズという仕組みは標準で
存在しませんので、operator << , operator >> などで、
自分で適切にポインタ内のデータを展開するなり、typeid を
保存しておくなり、自分でやっておかなければなりません。

そういう処理を自分で書いてください。

なお、有名なライブラリの boost(http://www.boost.org)等には
シリアライズ用のクラス群が存在します(一応C++汎用)し、
例えば MFC等の特定メーカのライブラリでも CArchive 等が存在します。
可能なら使ってみるのもありだと思います。


この投稿にコメントする

削除パスワード

No.3685

Re:オブジェクトをファイルに出力
投稿者---monkey(2005/04/24 07:17:12)


Banさんがすでに的確な回答をなさっていますので、私は簡単なサンプルをご提供。
<<演算子、>>演算子の第1引数(演算子の左オペランド)をofstream, ifstream
でなく、出力(入力)ストリームの基本クラスostream, istreamとしたことで、
ファイルだけでなく、標準入出力などにも使えるようにしているところがミソ。

#include <string>
#include <iostream>
#include <fstream>

class Thing {
    int n_;
    std::string s_;

public:
    Thing() : n_(0), s_( "test" ){}

    friend std::ostream& operator << ( std::ostream&, const Thing& );
    friend std::istream& operator >> ( std::istream&, Thing& );
};

std::ostream& operator << ( std::ostream& ostrm, const Thing& t )
{
    return ostrm << t.n_ << ' ' << t.s_ ;
}

std::istream& operator >> ( std::istream& istrm, Thing& t )
{
    return istrm >> t.n_ >> t.s_;
}

int main()
{
    Thing obj1;
    std::cin >> obj1; // 標準入力ストリームからの入力

    std::ofstream to( "test.txt" );
    to << obj1 << std::endl; // ファイルストリームへの出力
    to.close();

    Thing obj2;
    std::ifstream from( "test.txt" );
    from >> obj2; // ファイルストリームからの入力

    std::cout << obj2 << std::endl; // 標準出力ストリームへの出力
}



この投稿にコメントする

削除パスワード

No.3686

Re:オブジェクトをファイルに出力
投稿者---kaz(2005/04/24 23:47:03)


monkeyさん、Banさん、アドバイスありがとうございます。
やはりmonkeyさんに示していただいたプログラムのようにバイナリ形式のファイルではなくてTXT形式で保存するほうがよいのでしょうか?

実はSTLライブラリをつかってstackのなかのオブジェクトをオブジェクトとしてバイナリファイルにかきだしてstack自体を復元するということをしようとしていたのですが、stackのなかのオブジェクトのメンバにも別のオブジェクト(しかも継承したものなど)があり、やはりそのままオブジェクトとして書き出すのはすごく大変なのでしょうか?
JAVAのSerializableはじつはすごいものだと感じました。

C++で何かのデータ、たとえばゲームなどたくさんのデータがあるそのときの状態を保存するのにはどのような方法がよいのでしょうか?やはりXMLなどのある程度のフォーマットをつけて保存するのが定番でしょうか?なにかよい方法がありましたらお願いします。


この投稿にコメントする

削除パスワード

No.3687

Re:オブジェクトをファイルに出力
投稿者---Ban(2005/04/25 01:46:35)


monkey さんの例はシンプルさを優先してテキストにされてると思います。
結局、読み出し/書き戻し処理の定義を自分ですればテキストでも
バイナリでもやることは大差ありません。
(以下にあるような、動的情報を全て保存する必要は変わらない)


C++ は環境毎にデータの内部表現が違いますから、バイナリの場合、
形式やサイズなども自分で定義しておかないと環境に依存します。
このデータも保存する/形式をちゃんと決めてください。
# Java の場合は、どの環境でも同じになるとあらかじめ決めてある。

> 実はSTLライブラリをつかってstackのなかのオブジェクトを
-- snip --
> オブジェクトとして書き出すのはすごく大変なのでしょうか?

private なデータにアクセスできないというのは致命的かもしれませんが、
そうでなければ継承自体は静的な構造なのであまり関係ないと思います。
大抵は、typeid など型の識別コードを保持すればいいだけです。

ただポリモーフィックになってる場合、型と実体が異なっている可能性を
考慮する必要があります。(動的な情報は全て保存する必要があります)
# Java だと Object などの情報を使って処理を勝手に追加してるはず。


また、ネストしているクラスについても、その実体自体を保持
(コンポジション)なら単にそのクラスにシリアライズ用の入出力を
(用意して)自分の入出力時につかえばいいだけです。

注意が必要なのはコンポジションでない集約関係などの場合で、
複数から同一のインスタンスを参照している場合など、
依存関係の記録はちょっと面倒です。
インスタンスの識別情報が必要になってきますが、ポインタ値には
制限がでます。一致するか否かの判断には使えるとしても、
デシリアライズ時に同じアドレスにはならないでしょうから値に
意味はなくなります。考慮してください。


>JAVAのSerializableはじつはすごいものだと感じました。

まぁ Object とかリフレクションとか、サイズや実行効率の
デメリットと引き換えに利便性をとった、後発の言語ですから.....。
ユーザが意識しなくても裏でゴリゴリやってくれるわけですね。

ちなみに、C++ でも言語標準でないだけで、Serialize 機能を持たせた
クラス群が存在することは前述の通りです。これらを使えば、
ユーザが意識しなければならない処理を減らすのは可能です。

例えば CObject @MFC のシリアライズなんて、Java の
Serializableみたいなものですよ。
わざわざ CObject/Object なんてものが必要になるあたりも含めて。

> C++で何かのデータ、たとえばゲームなどたくさんのデータが
-- snip --
> なにかよい方法がありましたらお願いします。

用途によりますが、形式をきっちり決めて保存するのは定石かと。
簡単なツールなどならXMLやCSVなどを使うこともあるでしょうし、
ある程度の規模があるものは、バイナリの形式を定義して使うのが
普通だと思います。ゲームは大抵バイナリでしょう。
(改ざんを防ぐ目的などで暗号化するのが普通でしょうし)

例えば boost::serialization ならバイナリ/XML 両方でいけます。


この投稿にコメントする

削除パスワード

No.3695

ありがとうございます。
投稿者---kaz(2005/04/27 20:22:33)


BANさんありがとうございます。もう少し、調べてからどちらにするか決めようと思います。
アドバイスありがとうございました。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧




掲示板提供:Real Integrity