何かのようなもの:
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);
}
このスキームが機能するための条件は、サードパーティが提供するクラスで使用できる可能性が低いためです。最終的には、オブジェクトを自分で再構築するために必要なすべてのデータを保存し、このデータで作業する必要があります。