#بیشتر_بدانید
اینبار یه چیزی مینویسم تا کار سریالیز کردن کلاس ها و استراکت ها رو راحت تر کنه
#include <iostream>
#include <sstream>
#include <fstream>
#include <streambuf>
#include <string>
using namespace std;
//برای اینکه چک کنیم شی تابع سریالیز داره
// مبحث پست بالا همین بود
template<typename T,typename Sign>
struct has
serialize
{
template <typename U,U> struct AAA;\
template <typename A> static char Check(AAA<Sign,&A::serialize >* in);
template <typename A> static int Check(...);\
const static bool value = sizeof(Check<T>(0))==sizeof(char);
};
// برای نوع ورودی
struct BinaryIn
{
//لود کردن از فایل
void load(const char* filename)
{
fstream inf;
inf.open(filename,ios::in|ios::binary);
str<<inf.rdbuf();
inf.close();
}
//این برای موارد کلی هست
template<typename T>
void operator() (T& in)
{
// ارور برای وقتی که تابعه وجود نداره
staticassert(has
serialize<T,void (T::*)(BinaryIn&)>::value,"there are no member func Typename::serialize(BinaryIn&) to serialize object" );
in.serialize(*this);
}
stringstream str;
};
// از اینجا به بعد برای استثنا ها یا آن هایی که باید بیرون از کلاس سریالیزرشون تعریف شده باشه
// من یه چندتایی برای تست آماده کردم
template<>
void BinaryIn::operator() <int>(int& in)
{
str.read(reinterpretcast<char
>(&in),sizeof(in));
}
template<>
void BinaryIn::operator() <double>(double& in)
{
str.read(reinterpret_cast<char>(&in),sizeof(in));
}
template<>
void BinaryIn::operator() <float>(float& in)
{
str.read(reinterpret
cast<char*>(&in),sizeof(in));
}
// استرینگ خودش نوعی کلاسه اما چون استثنا هست این شکلی امکان لود بهش میدیم
template<>
void BinaryIn::operator() <string>(string& in)
{
sizet
ss;
str.read(reinterpretcast<char
>(&_ss),sizeof(__ss));
in.reserve(__ss);
char ins = new char[ss];
str.read(ins,ss);
in =
ins;
delete ins;
}
// برای خروجی
struct BinaryOut
{
// ذخیره کردن در یه فایل
void save(const char
filename)
{
fstream onf;
onf.open(filename,ios::out|ios::binary);
onf<<str.rdbuf();
onf.close();
}
template<typename T>
void operator() (T& in)
{
static_assert(has_serialize<T,void (T::)(BinaryOut&)>::value,"there are no member func Typename::serialize(BinaryOut&) to serialize object" );
in.serialize(
this);
}
stringstream str;
};
//استثنا ها
template<>
void BinaryOut::operator() <int>(int& in)
{
str.write(reinterpret_cast<char>(&in),sizeof(in));
}
template<>
void BinaryOut::operator() <double>(double& in)
{
str.write(reinterpret
cast<char*>(&in),sizeof(in));
}
template<>
void BinaryOut::operator() <float>(float& in)
{
str.write(reinterpretcast<char
>(&in),sizeof(in));
}
template<>
void BinaryOut::operator() <string>(string& in)
{
size_t _s = in.size();
str.write(reinterpret_cast<const char>(&
s),sizeof(in.size()));
str.write(in.cstr(),s);
}
// از اینجا به بعد یه مثال برای استفاده ازش هست
struct struct2
{
template <typename T>
void serialize(T& ar)
{
ar(a);
}
int a;
};
struct struct1
{
template <typename T>
void serialize(T& ar)
{
ar(a);
ar(b);
ar(c);
ar(d);
ar(e);
}
int a;
float b;
double c;
struct2 d;
string e;
};
int main()
{
struct1 a,b;
a.a=50;
a.b=80.0f;
a.c=410.0;
a.d.a=880;
a.e="Hello World!";
b.a=0;
b.b=0.0f;
b.c=0.0;
b.d.a=0;
b.e.clear();
BinaryOut tout;
tout(a);
tout.save("out.txt");
BinaryIn tin;
tin.load("out.txt");
tin(b);
cout<<b.a<<endl<<b.b<<endl<<b.c<<endl<<b.d.a<<endl<<b.e<<endl;
return 0;
}
تو مثال بالا محتویات
a
رو توی فایلی ذخیره میکنیم و
b
رو از روی همون فایل لود میکنیم
آخر کار هم تک تک محتویات
b
رو چاپ میکنیم تا خیالمون راحت شه که همه چیز ردیفه
محتویات و سایز
out.txt
رو بررسی کنید تا ببینید چه خبره
امیدوارم براتون جالب بوده باشه
@Simpleprogramming