ページ 11

C++ クラスの保存の仕方

Posted: 2010年4月22日(木) 00:45
by やっくん
C++においてクラスデータの保存機能を作りたいのですが、どのように実装しようか悩んでおります。
<仕様>
①初めてプログラム実行する場合はクラスのメンバに初期ファイルからデータを読み込む。
②”保存”を実行するとクラスを新規ファイルに保存する。
③2回目以降のプログラム起動時は1回目起動時に新規で保存したファイルからデータを読み込み、保存する際は読み込んだファイルと同じファイルを用いる。

現在、考えている方針が2つあります。
<方針1>
クラスメンバをテキストモードでクラス内部から読み書きする。

<方針2>
クラスをバイナリモードで外部から読み書きする。


このどちらが良いでしょうか。またこれ以外に良い方法があればアドバイスをもらえないでしょうか。

方針2に関しては実装自体可能かどうかがわかりません。
(C言語の構造体では可能でしたのでこちらもできるかなと思いました)

特にクラスが別のクラスを継承をしている場合、親クラスのメンバも方針2で扱えるのでしょうか。

Re:C++ クラスの保存の仕方

Posted: 2010年4月22日(木) 02:00
by YuO
シリアライズ機能ですか……。
方法は色々あるのですが,基本的にはメンバを自分で読んだり書いたりすることで実装します。
# C++にはリフレクションが存在しませんので……。

既存実装である,boost::serializationを使ってみるのがよいかもしれません。
SITE: Serialization
http://www.boost.org/doc/libs/1_42_0/li ... index.html
SITE: boost::serialize - Google 検索
http://www.google.co.jp/search?hl=ja&q= ... Aserialize

Re:C++ クラスの保存の仕方

Posted: 2010年4月22日(木) 02:03
by Justy
 シリアライズ、シリアル化、永続化とかで探すと情報が出てくるかと思います。

C言語関係掲示板 - オブジェクトをファイルに出力
http://f4.aaa.livedoor.jp/~pointc/No.3680.html

boost::serializationの使い方
http://hw001.gate01.com/eggplant/tcf/cp ... ation.html
boost Serialization
http://www.boost.org/doc/libs/1_42_0/li ... index.html


VC++テクニック : CArchiveクラスを使ってバイナリデータを読み書きする
http://www.alpha-net.ne.jp/users2/uk413 ... chive.html
CArchive クラス
http://msdn.microsoft.com/ja-jp/library/caz3zy5s.aspx

赤紫蘇2 XML/C++
http://akaxiso.sourceforge.jp/what_is_it.html


>方針1
 (運用環境的に問題ないのであれば)メンバをバイナリーモードで1つ1つ読み書きしてもいいと思います。
 ただテキストだろうがバイナリだろうが、クラスのメンバがポインタだった場合や
そのメンバが別のクラスだった場合等の処理も必要になります。
 
 又、メンバの追加・削除・修正があったときに過去に保存したデータが読み込めなくなることを
避ける仕組みも必要になるかもしれません。


>方針2
 これはクラス丸ごと std::fwriteとか std::ofstream::writeとかで書き出そうとしているということでしょうか?
 
 クラスはクラスでもC互換構造体であればうまくいくかもしれません。
 しかしそれ以外であれば書き出すことは出来ても読み出したときに元に戻る保証がないので、
事実上できません。


>このどちらが良いでしょうか。またこれ以外に良い方法
 基本方針1で、継承している場合は基底・派生クラスそれぞれが持っているメンバのみ取り扱う。
 仕組みを作るのが面倒であれば既存のライブラリを使う、といったところでしょうか。

 或いは手っ取り早く済ませるならC互換構造体をクラスにメンバとして持たせて、
C互換構造体の部分だけを方針2で保存とか。

Re:C++ クラスの保存の仕方

Posted: 2010年4月22日(木) 09:31
by たいちう
私の場合ですが、まず、読み書きする主体はクラスです。
自分のことは自分でするのがOOの基本でしょう。
クラスの種類が多く、継承をうまく使えない(多重継承は避けたいとか)場合には
別の方法を検討しますが、その方法はケースバイケースです。

次にテキストで書くかバイナリで書くかは、データの種類と量によります。
データが数値や文字列ならば、テキストデータにすることが殆どです。
テキストエディタで編集・確認できる強みは大きいですので。
とはいえ大量のデータだったり、あまり読まれたくない場合は、
何らかのフォーマットのバイナリデータとします。

# 読み書きの主体が自分自身と書きましたが、
# Hoge::ToString()やHoge::InitializeFromString(const string &data)
# とかを実装しておいて、他のクラスがファイルの読み書きをします。

Re:C++ クラスの保存の仕方

Posted: 2010年4月22日(木) 10:07
by やっくん
皆さん返信とアドバイスありがとうございます。

とりあえず皆さんから頂いたアドバイスを元に、
①boostを使う。
②メンバをそれぞれのクラスで保存する。
この2つをそれぞれ試してみようかと思います。

justyさんの仰った、
>C互換構造体をクラスにメンバとして持たせる
というのも良さそうでしたが、クラスをできるだけ分かりやすくしたいので今回はこちらの方針を取らないことにします。

バイナリ形式かテキスト形式の保存についてですが、データが数値や文字列なためとりあえずテキスト形式で書いてみることにします。(変更点などが最初は見れた方が楽なので)

Re:C++ クラスの保存の仕方

Posted: 2010年4月24日(土) 12:53
by やっくん
どうにかセーブ機能を実装できたので報告を。

最終的にコンストラクタでファイルからのデータの読み込み、メンバ関数で書き込みを作りました。
基底クラスと派生クラス別々に関数を作ったらうまく行きました。

皆さん、アドバイスありがとうございました。(^^