1

オブジェクトをファイルとの間で読み書きするためのジェネリッククラスを作成しようとしています。それをActiveRecordクラスと呼びました

クラス自体を保存するメソッドは1つだけです。

void ActiveRecord::saveRecord(){
 string fileName = "data.dat";

 ofstream stream(fileName.c_str(), ios::out);
 if (!stream) {
  cerr << "Error opening file: " << fileName << endl;
  exit(1);
 }
 stream.write(reinterpret_cast<const char *> (this), sizeof(ActiveRecord));
 stream.close();
}

今、私はこのクラスをUserクラスで拡張しています:

class User : public ActiveRecord
{
 public:
  User(void);
  ~User(void);
  string name;
  string lastName;
};

ユーザーを作成して保存するには、次のようにします。

User user = User();
user.name = "John";
user.lastName = "Smith"
user.save();

このActiveRecord::saveRecord()メソッドで任意のオブジェクトを取得し、クラス定義を取得して、送信したものをすべて書き込むにはどうすればよいですか?

のように見えるように:

void ActiveRecord::saveRecord(foo_instance, FooClass){
 string fileName = "data.dat";

 ofstream stream(fileName.c_str(), ios::out);
 if (!stream) {
  cerr << "Error opening file: " << fileName << endl;
  exit(1);
 }
 stream.write(reinterpret_cast<const char *> (foo_instance), sizeof(FooClass));
 stream.close();
}

そして、私たちがそれに取り組んでいる間、c++のデフォルトのオブジェクトタイプは何ですか。例えば。Objective-CではJavaではID、AS3ではオブジェクト、C++ではオブジェクトとは何ですか?

4

2 に答える 2

5
stream.write(reinterpret_cast<const char *> (foo_instance), sizeof(FooClass));

これはうまくいきません。 stringそのデータをヒープ (IIRC、16 文字より大きい場合) に割り当てます。再解釈キャストには、そのヒープ データは含まれません。

車輪を再発明しないでください。これは自明ではありませんが、解決済みの問題です。Google プロトコル バッファ、XML、またはブースト シリアル化ライブラリを使用します。

念頭に置いているのはテンプレートですが、POD (plain-old-data) 型以外では、それらの表現が明らかではないため、「任意のオブジェクトを単にシリアル化する」ことはできません。

さらにsizeof(BaseClass)、 User サブクラスでの使用は機能しません。サブクラスのメンバー データをキャストからスライスし、ファイルには入れません。

また、「c++ のデフォルトのオブジェクト型」はありません。

于 2010-05-23T02:58:08.847 に答える
1

あなたが提案していることは、深いシリアライゼーションを行わないため、オブジェクトが保持しているリソースの種類を一般的に知ることはできません。
任意のオブジェクトを格納できるようにするには、テンプレート関数を使用して、実際の格納を問題のクラスまたはそのフレンド (つまりoperator<<()) に委譲します。

template<class T> void ActiveRecord::saveRecord(const T& foo) {
    // ...
    stream << foo;
    // ...
}

operator<<()これが機能するには、問題のクラスにオーバーロードを提供する必要があります。

class Foo {
    friend std::ostream& operator<<(std::ostream&, const Foo&);
    // ...
    int a, b;
    // ...
};

std::ostream& operator<<(std::ostream& o, const Foo& f) {
    o << f.a << f.b;
    // ...
    return o;
}

しかし、Stephen が言ったように、シリアル化には独自のソリューションを作成するのではなく、実証済みのソリューションを使用してみませんか?

于 2010-05-23T03:07:56.637 に答える