0

オブジェクトをC++でシリアル化したい。最初は簡単な解決策を試しましたが、クラスの<<and>>演算子をオーバーロードしてシリアル化しました。このようにして、witch属性を選択してstrinstreamにシリアル化し、後で同じstringstreamを同じタイプの別のオブジェクトの属性に逆シリアル化することができます。これは、シリアル化するクラスに他のクラスへのポインターが含まれている場合は、それらのクラス>><<演算子もオーバーロードする必要があることに気付くまで機能しました。

そこで私は、オブジェクトをシリアル化してchar(1バイト)ごとにトラバースし、結果を文字列に保存するとどうなるかを考え始めました。その後、その文字列を取得して、元のクラスにreinterpret_castします。このようにして、含まれている内容を気にすることなく、また演算子をオーバーロードすることなく、あらゆるタイプの情報を含むあらゆるクラスをシリアル化することができます。

私はこの2番目の方法を実装しましたが、問題はありませんが、そうではありませんか?

#include <cstdlib>
#include <iostream>
#include <vector>
#include <stdlib.h>
using namespace std;

class B
{
public:
      B(int one , int two)
      { 
            this->one = one; 
            this->two = two;
      }
      int one;
      int two;      
};

class A
{
public:
      A(int one , int two, B b)
      {
            this->one = one; 
            this->two = two;
            classB= new B(b);
      }
      int one;
      int two;   
      B* classB;   
};

int main(int argc, char *argv[])
{
    B b(3,4);
    A* a = new A(1,2, b);


    //Serializing 'a'
    char v[sizeof(A)];
    for (int i =0 ;i<sizeof(A);i++)
    {
        v[i] = (reinterpret_cast<char*>(a)[i]);
    }

    char* cp = (char*)malloc(sizeof(char) * sizeof(A));
    for (int i =0 ;i<sizeof(A);i++)
    { 
        cp[i] = v[i];                          
    }

    A* aa = reinterpret_cast<A*>(cp);

    cout << aa->one << endl;
    cout << aa->two<< endl;
    cout << aa->classB->one<< endl;

    free(cp);
    system("PAUSE");
    return EXIT_SUCCESS;

// OUTPUT is as expect:
   1 
   2 
   3
}

それで、あなたはどう思いますか?2番目の方法に関する合併症を予測していますか?私はC++を初めて使用し、実用的な理論を開発しようとしていることを忘れないでください。

4

1 に答える 1

0

あなたが言及するこの2番目の方法(基本的にはデータ構造の生のバイトを読み書きするだけ)は、ポインターを格納するものでは機能しません。なんで?このようにそれを見てください:

struct S
{
    int* i;
};
S s;

s次のようなことをしての生のバイトを書いたとしましょうfile.write((char*)&s, sizeof(s))。これにより、ポインタの生の値が書き込まれますが、に格納されている値(つまり、によって返される値)iは書き込まれません。データ構造をリロードしようとすると、メモリの潜在的に無効な領域を指していることになります(これは、保存/ロードしたアドレスに格納されたアドレスであり、アドレスの内容ではないためです)。i*iii

于 2012-12-21T06:21:55.407 に答える