2

私は次の方法でオブジェクトをシリアル化する方法を知っています:

void encodeMsg(char **msg, const ConnectionParams& params)
{
    std::ostringstream oss;
    if (!(oss << params))
    {
        //failure
    }
    msg = oss.str();
}

メッセージを逆シリアル化してオブジェクトに戻すにはどうすればよいですか?

つまり、このメソッドが必要です。

ConnectionParams encodeMsg(char *msg)
    { ... }

だから私はinstringstreamオブジェクトを持っていません...どうすればそれを行うことができますか?

4

1 に答える 1

1

何かのようなもの:

ConnectionParams decodeMsg(char *msg)
{
  ConnectionParams ret;
  std::istringstream iss(msg);
  iss >> ret;
  return ret;
}

これは、このクラスがでシリアル化可能になっていることを前提としてoperator<<おり、対称的に反対の操作を提供しますoperator>>。内部を知らずに任意のC++オブジェクトをシリアル化する方法はありません。この回答では、これらの操作はクラスプロバイダーによってすでに実装されていると想定しています。

また、次のように、おそらくConnectionParamsを参照として渡す必要があることに注意してください。

void encodeMsg(char *msg, ConnectionParams& ret);

また、encodeMsgが間違っているため、次のように機能する可能性が高くなります。

void encodeMsg(char **msg, const ConnectionParams& params)
{
    ....
    *msg = oss.str();
}

oss.str()はossから内部ポインターを返し、関数の戻り時にossが破棄され、ポインターが無効になるため、呼び出し元に返すことができないため、これも間違っています。std::stringなどを返す方がよいでしょう。

編集:クラスがそれ自体をシリアル化および逆シリアル化する手段を提供しない場合はどうなりますか?十分に単純で、ヒープに割り当てられたポインターやファイル記述子を保持せず、コンストラクターやデストラクタで派手な動作をしないクラスでは、古いC構造体と同じように実行できる場合があります。つまり、すべてのバイトを解釈します。バッファとして。これは危険であり、タイプは安全ではなく、バッファは異なるコンパイラ/アーキテクチャ間で相互運用できない可能性があることに注意してください。

// DISCLAIMER: Untested code!

class A {
  int plain_variable;
  char palin_array[50];
};
// Class A is ok to serialize this way

class B {
  A plain_object_array[10];
  double another_plain_variable;
};
// Class B is ok to serialize this way

class C {
  float plain_object;
  std::string fancy_string;
};
// Class C is *NOT* ok to serialize this way, because it contains an string,
// which, in turn, contains a heap allocated pointer

template<class T>
void serialize(const T& obj, std::string& buff)
{
  const char *accessor = (const char *)&obj;
  std::string tmp(accessor, sizeof(obj));
  std::swap(buff, tmp);
}

template<class T>
void deserialize(const std::string& buff, T& obj)
{
  char *accessor = (char *)&obj;
  std::copy(buff.begin(), buff.end(), accessor);
}

このスキームが機能するための条件は、サードパーティが提供するクラスで使用できる可能性が低いためです。最終的には、オブジェクトを自分で再構築するために必要なすべてのデータを保存し、このデータで作業する必要があります。

于 2012-06-17T17:15:50.073 に答える